views:

238

answers:

3

I'm learning about MVVM and one of the things I don't get is how the model and the view model are supposed to communicate. I also don't understand whether they are separate classes, composite classes, or whether the ModelView is supposed to inherit from the model.

I need to get some data from a web service, so I think the model should be responsible with it and make the appropriate web service calls. But since these requests really originate in the view as a result of the user wanting to see some information it means the ModelView has to forward that request to the model somehow, then provide an asynchronous notification mechanism so that the view isn't stuck while the model asynchronously retrieves the data. To summarize, suppose we have the following use case:

View: ComboBox --> bound to List in ModelView. Model view is connected to Model in (?????) way. The data that will populate the list can be retrieved by a web service call. How does this scenario work?

+1  A: 

In short, the view model is fully aware of the model and can interact with it directly. Don't overthink the interaction between them. The only double-blind relationship is that between the view and the view model.

Adam Robinson
When you say double blind do you mean the view and the model?
Rire1979
@Rire: No, there is no relationship between the V and the M (for clarity's sake I'll use the abbreviations). The M doesn't know about the VM or the V. The VM knows about the M. The V doesn't know about anyone. In short, the *only* component that is aware of another component is the VM, and it's only aware of the M.
Adam Robinson
I see no problem with the V knowing about the VM, so dont get hung up on this point @Rire
Schneider
A: 

I think it is worth mentioning that you do not always need three different classes for your MVVM "combos". The V will always be its own class, the VM will probably also need its own class (I don't think it has to, though), but the M can be the same across the entire project if that suits your application. If you are building a small application, let's say you only have 10-15 different service methods in total, it will probably make sense to have one single class responsible for calling your web service, handling errors and making the asynch callbacks to the various VMs. And if you are building a really small app, maybe it will make sense to have only one VM and, say, 2-3 Views that bind to that single VM. Maybe in that case you don't even need a separate Model class at all, just call the web service directly from your VM. After all, you will have created a service reference to that web service. The generated proxy classes will then act as your Model.

What I am trying to point out is that when reading about MVVM it is easy to assume that there will always be three physical files for each MVVM "combo". That is what I thought when I started experimenting with MVVM, and I thought to myself "Wow, that's a lot of files. And Wow, what if I have some common methods in the web service that need to be called by multiple Model classes, then I will have tons of duplicated code all over the place.". But when my head cleared I realized that it's up to me to decide what works best in my app.

Henrik Söderlund
Thanks for the clarification.
Rire1979
+3  A: 

Let's make your scenario a bit more complicated: user clicks a button and then a list needs to be populated with a data that comes from a web service.

In this scenario:

  • View's list is bound to ObservableCollection in ViewModel.
  • View's button is bound to a command in ViewModel.
  • ViewModel's command's handler will fire an asynchronous request to a web service and subscribe a listener that will handle a response.
  • The response handler will populate the observable collection with the items from the response once it's received. Since View is bound to the ObservableCollection it will automagically update its list on the screen.

Now whether you encapsulate a web service call in an another class (e.g. Model) or leave it in ViewModel highly depends on your own preferences (e.g. having it in a model allows to to easily test ViewModel by injecting a mock rather than having a web service running, etc.)

PL