What is the model for MVVM?

I read several articles, tutorials, and blog posts about the MVVM pattern. However, there is one thing that I do not understand. Accepting three "layers":

  • Model
  • View
  • View Model

As far as I understood MVVM, the model contains "raw" data, for example. name and address in the case of class Student . A view model provides view properties that represent model data.

Example for a property in a view model

 public string Name { get { return model.Name; } set { model.Name = value; } } 

Example for model

 private string name; public string Name { get { return name; } set { name = value; } } 

This may seem a little silly, but doesn't that create redundancy? Why do I need to save the name in the model and in the view model? Why can't the view model name be fully processed?

+6
source share
5 answers

In such a simple example, this answer would be yes (it is unreasonably redundant). But, presumably, the page will contain more than just one model object. You may have a page state, as well as several other model objects that you need to track. This is done in the ViewModel.

For example, you may have additional information about a registered user displayed in the status bar, as well as a service running to detect changes in a text file.

You may also have a form for editing the Student object. If you intend to verify these changes, you will not want to directly edit the Student object until the changes are verified. ViewModel can act as a temporary storage place in this case.

Note on the above: in the model, checks are not rare, but even then you probably want the user to be able to enter invalid values ​​while editing the form. For example, if your model does not allow a value of zero length in a field, you still want your user to delete the value, move to another field (for example, to copy it), then return to the field and finish editing (paste). If you are tied directly to the model, your verification logic may not process this state “in the gap”, “not yet finished”, as you would like. For example, you may not want to contact your user with verification errors until they have finished and clicked "Save."

You probably also have Command objects in the ViewModel to handle button clicks, etc. These would be domain specific objects that would be useless in the model.

ViewModels are also useful when you need to filter or somehow temporarily “modify” model objects to get something useful on the screen. For example, you can display a list of all users in the system along with a list of the ten best artists from them in real time (updated every 10 seconds). Or you can show a list of reports and a graph showing the overall speed of use, etc. Filtering, sorting and tuning this data will take place in the ViewModel.

A model, on the other hand, is usually as clean as possible. Ideally, you want POCOs , which (as a rule) simulate exactly what is in your persistent storage (database or what you have). If your persistent storage has FirstName and LastName fields, then your model also. Only in your ViewModel would you combine them to get the Name field (either "First Last" or "Last, First" depending on the needs of the View).

For instance:

 namespace Model { public class Student { public string FirstName { get; set; } public string LastName { get; set; } } public class Class { public string Name { get; set; } public float Score { get; set; } } } namespace ViewModel { public class EditStudentRecordViewModel { private Model.Student _student; private IEnumerable<Model.Class> _studentClasses; /* Bind your View to these fields: */ public string FullName { return _student.LastName + ", " + _student.FirstName; } public string FirstName { get; set; } public string LastName { get; set; } public IEnumerable<Model.Class> PassingClasses { get { return _studentClasses.Where( c => c.Score >= 78 ); } } public IEnumerable<Model.Class> FailingClasses { get { return _studentClasses.Where( c => c.Score < 78 ); } } public void Save() { List<string> l_validationErrors = new List<string>(); if ( string.IsNullOrEmpty( this.FirstName ) ) l_validationErrors.Add( "First Name must not be empty." ); if ( string.IsNullOrEmpty( this.LastName ) ) l_validationErrors.Add( "Last Name must not be empty." ); if ( l_validationErrors.Any() ) return; _student.FirstName = this.FirstName; _student.LastName = this.LastName; Model.Utilities.SaveStudent( _student ); } } } 
+5
source

A model is a graphic object that contains your business logic.

Where you keep the behavior (validation, calculation, etc.).

ViewModel is what models the user interface and its interactions.

These are different and have different reasons for the existing one - the point of the template is to separate your display logic to VVM (View and ViewModel) and completely separate your business logic.

+5
source

A view model is where you will track properties that are specific to the view and not necessary for the model.

Take your model, suppose it is called Person .

And then you create a view model for Person called PersonViewModel , which looks like this:

 public class PersonViewModel { public Person Person { get; set; } } 

(Note that you may not want to expose this model directly, but this is a different story)

Now let's say that you have a button in the view that is used to save the instance of Person . To provide a better user interface (UX), you only want to enable the button if your model has really changed. Thus, you implement the INotifyPropertyChanged interface in the Person class:

 public class Person : INotifyPropertyChanged { ... 

Now you can open the HasUnsavedChanges property from your Person , to which the Enabled property on the save button is bound, but this logic has nothing to do with the person.

This is where the view model appears. You must define this property for the view in the view model, for example:

 public class PersonViewModel { public Person Person { get; set; } public bool HasUnsavedChanges { get; set; } } 

Then your view model will subscribe to the PropertyChanged event of the INotifyPropertyChanged interface and switch the HasUnsavedChanges property to the view model.

Then, if the binding is configured correctly, the save button will enable / disable when any change occurs on your model, but your model does not have any logic linking it to the view.

Please note that you will also need to implement INotifyPropertyChanged in the view model so that your view is perceived when you make changes to the view model to which it is attached.

Again, a point acts like a bridge to contain logic, which is a combination of model properties and presentation properties that do not belong to the model.

+4
source

I have always considered Models as the “building blocks” of an application. They are usually self-contained classes with some properties and, possibly, some rudimentary verification or logic only for their own properties.

View models, on the other hand, are my actual application classes, which ultimately use the “building blocks” (Models) when creating and running the application. They perform functions such as performing advanced validation, processing commands, processing events, any business logic, etc.

It should be noted that you do not need to disclose your model properties in your ViewModel, as in your code example. This is the Purist MVVM approach, since it completely separates your Model layer from the View layer, but is also quite acceptable to expose the entire model to view. This is what I usually use in most small projects because of the simplicity and lack of code duplication.

 public MyModel CurrentModel { get { return _model; } set { if (_model != value) { _model = value; RaisePropertyChanged("CurrentModel"); } } } 

However, if there are cases when the view requires only a few properties from the Model, or if the project is large enough and I want the layers to be completely separated, I show the model properties in the view through the ViewModel, as in your code example.

+1
source

The MVVM model is exactly the same as in MVP or Model2 MVC. This is one part of MVC-inspired templates that is not affected by theme variations.

A model is a layer that contains repositories, units of work, domain / model objects, data maps, services, and some other structures. All that they combined creates a model layer that contains all the domain business logic for a particular application.

A model is not a single instance. Anyone who divides you is full.

The specific usecases for which MVVM was designed is a situation where you cannot change either the model or view, or both.

PS Although, if you use ViewModel instances according to the ASP.NET MVC documentation, you are NOT actually using MVVM. It's just Model2 MVC with different names for things (where "viewmodels" are actually views and "views" are templates). They seemed to mess up when they sold the Rails-like architecture as "MVC."

0
source

All Articles