I'm completely new to M-V-VM and very new to Silverlight, just reading about it for the first time today. As a sample, I am creating a model containing a list of items. My (Silverlight 4) View contains a listbox and my ViewModel will look to the model to retrieve the collection that the listbox will bind to.
My question is this. I think it would be good to use an ObservableCollection to hold the items that the listbox binds to. This would be an ObseravleCollection in the ViewModel. Should I also use this type of collection in the model, or should I use another collection type and do smoe conversion between model and viewmodel?
There are 3 basic scenarios (in order of increasing complexity):
model simply provides an access to a backend services and does no caching of data flowing through it at all
model exposes a collection of items, vms don't have their own collections, and then views are simply bound to collection in model object
model exposes a data source, vms have their own collection that serve as window into this data source, and views are bound to collections in vms.
In first case you'd use List to simply pass a requested data to vms, in other cases you'd use ObservableCollection so that either views will be properly updated via binding (case #2) or vms can properly update its own collections (case #3)
the usual way of doing this is to use IList/List or something similar in the model and then do a conversion in the ViewModel. So in the model you will have something like IList and in the ViewModel you convert it to ObservableCollection (usually in the ViewModel's constructor).
Cheers, Alex
Related
For a openui5 component I need to bind multiple models and is investigating what the best way to do this is.
The models are both JSONModel and XMLModel.
The background is that I want provide the user choice of multiple source to use for the custom openui5-spitz-reader component https://github.com/elsewhat/openui5-spritz-reader
Each of the selection the user can make (BBC World News, Reddit /r/worldnews), has a single Model populated.
During runtime, I need to combine all the Models the user has selected and bind the combined content towards the items aggregation of the openui5-spitz-reader component.
You can use named models on aggregations see Multimodel Support - example using multiple models on an element JSBin OData Model dynamic column and data binding
I am not sure if you can bind data from 2 models on a single aggregation, you may be able to achieve it using a factory function with the aggregation or a handler on the model binding - using a generic binding to sum aggregation
I have a quick (hopefully) question on how to implement a composite field using MVVM.
I have 2 examples, one is on the sql end I am storing gps coordinates in the following manner "Latitude,Longitude" for instance "45.55555,-80.00000". the other example is storing feet and inches as a single double field with it being ft.in.
How should I go about this? Should I have two fields and in the model or Viewmodel composite them if the other piece exists? Should I bind them to the same field and somehow validate the sets?
thanks!
In the Model I normally use a structure/layout that is closest/easiest to the source so it can be easily/quickly read and written.
In the ViewModel I aim for a representation of the View to accommodate the bindings.
In general I make the ViewModel responsible for the transformation between the Model and ViewModel.
So whether or not a property of the ViewModel and the Model should have one field or two depends on the requirements of the View and the Source.
I'm trying to learn MVVM, and i'm struggling a little on differentiating between a model and viewmodel.
If someone could answer these 2 questions it would help clear a lot up for me:
Say I have an Objects class, which is a viewmodel that contains multiple ObservableCollections of Object.
The Object class contains an ObservableCollection of strings that are displayed on the GUI.
Is the Object class a model or viewmodel?
What if the Object class contains just a string and a integer (name and value), is it a model or viewmodel?
The Model is the class that holds your data. The data can be strings /integers or whatever.
The Model can also be a list / collection of those objects. For example a List of Person objects can still be your Model.
The ViewModel is the tier between your Model and the View. It should be used to perform whatever tasks you need on the data (for instance, if your Model is a list of Person objects but you only want to show in your view people that are aged older then 18, this logic is done in the ViewModel)
So to answer your question:
If you have an object which contains the data (in your example a list of strings) it is the Model.
Even if the object is a little more complex (with relation to the number of properties it holds) it's probably still the Model.
Business Logic should be kept separate from the model. On the other hand Validation can be added to the Model (for instance to make sure the Age property of a person is non-negative) since this is still rules on how your data should behave
A "Lookup" in this example is an IList<string> of state abbreviations. Generally, your Domain Model POCOs won't include these options. ViewModels usually take this responsibility referencing both the original Domain Model as well as the Lookup object, but what happens when the Domain Models are nested and you are using MVC templates (which won't have access to the original Model's root properties?
Is there a way to include the Lookups in one object and the Model in a different object for the template? Is it permissible to assemble on-the-fly a ViewModel specific to that Template within the View (which would have to include any nested data from there)? I would think static methods to pull down Lookup values is bad.
Any ideas?
Notes (to my knowledge):
A Domain Model POCO from a repository doesn't change in structure. If you need a single Model to have both the Customer object and the DDL options for US State for example, you normally have a ViewModel that references the Customer object and the Customer Lookup lists.
However, when you have a nested Domain Model (aggregate root), the nested objects have no where to put the Lookup Lists, and the MVC templates cannot access the root level View Model (their view model is the partial Model).
Edit:
Is there some way to put the DDL lists in the root level of the ViewModel, then when you get to the Customer object, construct a new ViewModel that references the root level DDL lists and the current Customer object to send to the template? This would eliminate duplicate data in the Model as well as use a single Model for all the Views. The only bad would be Controller like data assembly code in your view (which is just as bad).
A couple of suggestions. First, use separate view models for your views -- don't directly use your domain models. These view models can, and should, carry the extra data needed by the view. Second, you can use the overloads on DisplayFor/EditorFor to pass additional view data to the template. That way your template can be specific to a particular domain model and yet have access to the additional data in the view model.
For static, unchanging lists like state abbreviations, you could use Application state or Cache entry. These types of lists could be loaded in Application_Start from a database.
I've recently refactored my application with the following:
Linq to SQL db connection
Objects to wrap the linq to sql classes
Mappers to map back and forth between objects and Linq to Sql entitys
Service layer to call the repository, handing up objects to the UI.
Before I was just using Linq to SQL objects in my UI (I know). But when displaying relations it was so easy. For instance:
I have a able called SchoolProfile, and a table called School. A user has a SchoolProfile (with GPA, Rank, etc..) , which links to a School. The School adding functionality was easy - because it has no foreign keys.
When creating a form for a user to list all SchoolProfiles - they dont want to see a SchoolId. Before in my view it would simply be schoolprofile.School.Name. Now a ShoolProfile is a "flat" object in my ViewData with no properties. I guess I could create other classes to get the related data (name of the school, etc..) but that feels messy. Any suggestions?
My suggestion is to look at ViewModels and AutoMapper. Basically you will create a specific ViewModel for your View and you can include SchoolName as a property of that ViewModel. Then you can use AutoMapper to map from your Domain Model (form Linq to Sql) to your ViewModel easily.
Basically, you want your View to get all the information it needs from the ViewModel. So design your ViewModel based on all the info you need to display. So all it needs to do is take what is in the ViewModel and spit it out.