2013-05-14 26 views
36

Hãy nói rằng tôi có một trang cho phép chỉnh sửa các chi tiết của người dùng, vì vậy tôi có một ViewModel như thế này:ASP.NET MVC - Làm thế nào chính xác để sử dụng Xem Models

public class UserViewModel { 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public int ManagerId { get; set; } 
    public string Category { get; set; } 
} 

Vì vậy, về hành động edituser tôi của tôi có thể đã này qua lại bằng mô hình chất kết dính và sau đó tôi có thể lập bản đồ đó đến domain model:

public ActionResult EditUser(UserViewModel user) { 
    ... 

Tuy nhiên, trang đó sẽ hiển thị dưới dạng cũng cần chi tiết như một danh sách các nhà quản lý và các nhóm để cung cấp Dropdowns cho những lĩnh vực đó. Nó cũng có thể hiển thị danh sách những người dùng khác trong thanh bên để bạn có thể chuyển đổi giữa những người dùng khác nhau mà bạn đang chỉnh sửa.

Vì vậy, sau đó tôi có một mô hình điểm:

public class ViewUserViewModel { 
    public UserViewModel EditingUser { get; set; } 
    public IEnumerable<SelectListItem> Managers { get; set; } 
    public IEnumerable<SelectListItem> Categories { get; set; } 
    public IEnumerable<SelectListItem> AllUsers { get; set; } 
} 

Đây có phải là cách chính xác để làm điều đó? Cả hai đều là Người mẫu? Nếu vậy, có quy ước đặt tên tôi nên sử dụng để tôi có thể phân biệt giữa các máy ảo giống như các mô hình và máy ảo chỉ chứa dữ liệu cho trang không?

Tôi đã nhận được tất cả điều này sai?

Trả lời

20

Làm thế nào tôi làm điều này trong shortcut:

  1. Tạo lớp ViewModel riêng cho từng trên trang, sau đó tôi hiển thị các lớp này với PartialViews là @{Html.RenderPartial("PartialName", Model.PartialModel);}.
  2. Nếu trang chứa những thứ như html metas, tôi tạo lớp riêng cho metas và đặt nó trong phần trên trang.
  3. Các trường hợp còn lại như "tôi có nên đặt điều này trong lớp riêng biệt không?" là sự phán xét của bạn.

Vì vậy, ví dụ: bạn có trang có một số loại thanh đăng nhập/đăng ký hoặc bật lên bất cứ điều gì.

public class SomePageViewModel 
{ 
    public RegisterBarVM Register { get; set; } 
    public LoginBarVM LoginBar { get; set; } 

    public MetasVM Metas { get; set; } 
    public string MaybePageTitle { get; set;} 
    public string MaybePageContent { get; set;} 

    [HiddenInput(DisplayValue = false)] 
    public int IdIfNeeded { get; set; } 

    public IEnumerable<SelectListItem> SomeItems {get; set;} 
    public string PickedItemId { get;set; } 
} 

public class RegisterBarVM 
{ 
    public string RegisterUsername {get;set;} 
    public string RegisterPassword {get;set;} 
    //... 
} 

public class LoginBarVM 
{ 
    public string LoginUserame {get;set;} 
    public string LoginPassword {get;set;} 
    //... 
} 

//cshtml 
@model yourClassesNamespace.SomePageViewModel 
@{ 
    Html.RenderPartial("LoginBar", Model.LoginBar); //form inside 
    Html.RenderPartial("RegisterBar", Model.RegisterBar); //form inside 

    using(Html.BeginForm()) 
    { 
     @Html.EditorFor(m => m.IdIfNeeded) 
     @Hmtl.EditorFor(m => m.MaybePageTitle) 
     @Hmtl.EditorFor(m => m.MaybePageContent) 

     @Hmtl.DropDownListFor(m => m.PickedItemId, new SelectList(Model.SomeItems)) 

     <input type="submit" value="Update" /> 
    } 
} 

@section Metas { 
    @{Html.RenderPartial("Meatas", Model.Metas} 
} 

Giới thiệu về mẫu trình chỉnh sửa Brad Wilsons Blog và chỉ google hoặc tìm tài nguyên ngăn xếp về mẫu hiển thị/trình chỉnh sửa và HtmlHelpers. Tất cả đều rất hữu ích để xây dựng các trang web nhất quán.

9

Cá nhân tôi thích đặt tất cả thông tin cần thiết cho trang để hiển thị trong ViewModel, vì đó là mục đích của ViewModel - để cung cấp tất cả dữ liệu cho Chế độ xem. Vì vậy, UserViewModel của tôi sẽ chứa các thuộc tính cho Managers, CategoriesAllUsers và bộ điều khiển sẽ lấp đầy các bộ sưu tập đó trước khi chuyển ViewModel sang chế độ xem.

Đây thực chất là những gì bạn đã làm - nó chỉ xóa ViewModel phụ khỏi phương trình.

Tôi cũng đã thấy các lập trình viên khác sử dụng ViewData để gửi danh sách thả xuống đến chế độ xem, nhưng tôi không thích điều đó vì Chế độ xem không được nhập mạnh mẽ, trong khi đó ViewModel là.

93

"Xem mô hình" chỉ là một mẫu. Không có gì huyền diệu về tên, nhưng nói chung bất kỳ lớp nào được chuyển sang một chế độ xem (cho dù chỉ hiển thị dữ liệu hoặc cho mục đích gửi biểu mẫu) được gọi là "mô hình xem" và được đặt tên như FooViewModel hoặc FooVM để cho biết nó là một phần của mô hình "xem mô hình" đó.

Tôi không muốn đi quá triết học về bạn, nhưng tôi nghĩ rằng một chút tham khảo về các mô hình chơi sẽ rất hữu ích. ASP.NET MVC rõ ràng là đủ khuyến khích một mô hình kiến ​​trúc MVC (Model-View-Controller). Trong MVC, Mô hình là vùng chứa cho tất cả logic nghiệp vụ của ứng dụng. Bộ điều khiển chịu trách nhiệm xử lý yêu cầu, tìm nạp mô hình, hiển thị Chế độ xem với mô hình đó và trả về một phản hồi. Điều đó có vẻ như rất nhiều trách nhiệm nhưng trong thực tế, khung công tác xử lý hầu hết điều này đằng sau hậu trường, vì vậy Bộ điều khiển thường (và phải là) rất nhẹ trên mã. Họ chịu trách nhiệm cho số tiền tối thiểu của chức năng để dây tất cả mọi thứ lên. Cuối cùng, Chế độ xem chịu trách nhiệm tạo lớp giao diện người dùng cho phép người dùng tương tác với dữ liệu trong Mô hình. Đó là không phải là chịu trách nhiệm về chính dữ liệu, cũng không phải là nó (ViewData/ViewBag là một vi phạm khá lớn ở đây, ít nhất là bằng cách nó được các nhà phát triển sử dụng trong thực tế).

Vì vậy, điều đó có nghĩa là phần lớn logic ứng dụng của bạn phải nằm trong mô hình của bạn và thường đó là một điều tốt. Tuy nhiên, kể từ khi mô hình là thiên đường của dữ liệu ứng dụng, nó thường được lưu giữ trong cơ sở dữ liệu hoặc tương tự.Điều đó tạo ra một số xung đột lợi ích vì bây giờ bạn cần phải bắt đầu một hành động cân bằng giữa những dữ liệu nào cần được duy trì và dữ liệu nào sẽ chỉ tồn tại cho mục đích hiển thị.

Đây là nơi mô hình xem có sẵn. MVVM (Model-View-View Model), một mẫu hơi song song với MVC, nhận ra các vấn đề cố hữu trong cách tiếp cận một mô hình-tất cả-quy tắc-tất-cả-nguyên-tất cả. Tôi sẽ không đi sâu vào chi tiết ở đây, bởi vì MVC không sử dụng mẫu này. Tuy nhiên, hầu hết các nhà phát triển ASP.NET MVC đã đồng lựa chọn Mô hình Xem của MVVM. Những gì bạn về cơ bản kết thúc với một thực thể cơ sở dữ liệu được bảo vệ (mô hình truyền thống) và sau đó thường là nhiều mô hình chế độ xem khác nhau đại diện cho thực thể đó ở các trạng thái khác nhau. Điều này cho phép mô hình của bạn chứa logic nghiệp vụ liên quan đến sự kiên trì trong khi (các) mô hình khung nhìn chứa logic nghiệp vụ liên quan đến hiển thị, tạo và cập nhật mô hình đó.

Tôi đã đi theo dõi một chút, nhưng dài và ngắn là những gì bạn đang làm là hoàn toàn chấp nhận được. Trong thực tế, đó là thực hành tốt. Tạo nhiều kiểu xem như ứng dụng của bạn yêu cầu và sử dụng chúng để lưu trữ dữ liệu và logic nghiệp vụ cần thiết cho các chế độ xem của bạn. (Điều đó bao gồm những thứ như SelectList s Cả điều khiển cũng không xem mình nên cần phải biết làm thế nào để tạo ra một SelectList cho một thả xuống..)

+6

Giải thích tốt nhất về chủ đề này. Bạn nên đặt nó trên một Blog! +1 –

+0

Bạn đã đề cập đến các mô hình phải chịu trách nhiệm về logic kinh doanh của ứng dụng. Bằng cách kinh doanh, bạn có thể có nghĩa là tất cả việc chuẩn bị dữ liệu, truy vấn, lọc, chiếu mô hình này sang mô hình khác, hoặc một ViewModel cụ thể. Và sau đó ViewModel chuẩn bị như vậy được chuyển đến View bằng bộ điều khiển. Làm thế nào để bạn thể chất làm điều đó? Làm thế nào để bạn thiết kế mô hình để làm kinh doanh? Ví dụ, bạn có chuyển tất cả các phương thức của bộ điều khiển sang các lớp đại diện cho các mô hình khung nhìn không? Hiện nay, tôi có rất nhiều chức năng và "kinh doanh" trong bộ điều khiển mà làm tất cả các bit và bu lông. thanks – Celdor

+0

Thành thật mà nói, bạn không thể thực sự làm điều đó trong ASP.NET MVC. Để thực sự hiểu những gì tôi đang nói về, hãy xây dựng một ứng dụng mẫu trong Ruby on Rails. RoR tuân thủ các mô hình MVC rất nghiêm ngặt, và bạn sẽ thấy chính xác có bao nhiêu đi vào mô hình của họ. ASP.NET MVC, mặt khác chỉ tuân thủ một cách lỏng lẻo với MVC. Bạn "Mô hình" sẽ là một số kết hợp của các lớp thực thể, các mô hình khung nhìn, và một cái gì đó giống như một kho lưu trữ hoặc dịch vụ. Bạn nên cố gắng giữ bộ điều khiển của bạn mỏng, bạn không thể di chuyển * tất cả * logic vào một lớp. –

Các vấn đề liên quan