This article is currently in the process of being translated into Vietnamese (~31% done).
ViewModels
Chúng ta đã làm việc với Models nhiều lần trong bài giảng này nhưng nếu bạn nhìn trong bài giảng về ASP.NET MVC hay chỉ là mẫu MVC nói chung thì bạn có thể thấy rằng "View-Model" được nói đến. Nhưng sự khác biệt giữa Model và ViewModel là gì? Thực tến bất cứ khi nào bạn truyền một Model tới View thì được coi là ViewModel bởi nó dùng trong View. Hay nói cách khác, không có sự khác biệt - bạn có thể dùng Model như ViewModel hay ngược lại.
Tuy nhiên, có nhiều tình huống mà bạn muốn tạo ra một ViewModel riêng biệt cho một View nhất định. Có thể mở rộng hay đơn giản hóa một Model đã tồn tại hay vì bạn muốn hiển thị gì đó trong View mà không có trong model.
ViewModels are often placed in their own directory in your project, called "ViewModels". Again, this is just a convention and since ViewModels are just regular .NET classes, you are free to place them where ever you want to, but it often makes sense to follow these conventions. Some people also prefer to postfix the name of the class with the word ViewModel, e.g. "AddressViewModel" or "EditUserViewModel".
When to use a ViewModel?
Here are a couple of situations where you could benefit from a ViewModel:
Dùng ViewModel để mở rộng những thứ trong View mà không tồn tại trong View sẵn có:. Khi bạn muốn đưa Model tới View, bạn có thể truyền các kiểu dữ liệu cơ bản như String nhưng nếu phức tạp hơn thì dùng ViewModel:
public class AddressViewModel
{
public string StreetName { get; set; }
public string ZipCode { get; set; }
}
To access the data of multiple Models from the same View: This is relevant in a lot of situations, e.g. when you want to create a FORM where you can edit the data of multiple Models at the same time. You could then create a ViewModel like this:
public class EditItemsViewModel
{
public Model1Type Model1 { get; set; }
public Model2Type Model2 { get; set; }
}
To simplify an existing Model: Imagine that you have a huge class with information about a user. Perhaps even sensitive information like passwords. When you want to expose this information to a View, it can be beneficiary to only expose the parts of it you actually need. For instance, you may have a small widget showing that the user is logged in, which username they have and for how long they have been logged in. So instead of passing your entire User Model, you can pass in a much leaner ViewModel, designed specifically for this purpose:
public class SimpleUserInfoViewModel
{
public string Username { get; set; }
public TimeSpan LoginDuration { get; set; }
}
To extend an existing Model with data only relevant to the View: On the other hand, sometimes your Model contains less information than what you need in your View. An example of this could be that you want some convenience properties or methods which are only relevant to the View and not your Model in general, like in this example where we extend a user Model (called WebUser) with a LoginDuration property, calculated from the LastLogin DateTime property already found on the WebUser class:
public class WebUser
{
public DateTime LastLogin { get; set; }
}
From there on there are two ways of doing things: You can either extend this class (inherit from it) or add a property for the WebUser instance on the ViewModel. Like this:
public class UserInfoViewModel
{
public WebUser User { get; set; }
public TimeSpan LoginDuration
{
get
{
return DateTime.Now - this.User.LastLogin;
}
}
}
Or like this:
public class ExtendedUserInfoViewModel : WebUser
{
public TimeSpan LoginDuration
{
get
{
return DateTime.Now - this.LastLogin;
}
}
}
Summary
A ViewModel is basically just a Model passed to a View, but as outlined in this article, there are many ways of doing this - you can either use an existing Model, as it is, or create a new one, specific to the View in question.