Introduction to ViewModels
The ViewModel in MDriven is a core piece of the Framework. The UML model contains all the information about the application, but doesn't have clear perspectives or views of how that information should be used. It is a generalized bucket of data. The views, on the other hand, put perspective on the modeled information.
Views are used for several things in an MDriven Framework application. The most common use is the user interface of the application, but others are used to create APIs that are either read-only or read-right, in the same way that the user interface is, a lot of times, both read and write.
The ViewModel is also used for extracting data either as JSON or XML, or to create reports either as XML exports or by using the report features. It can be merged into the output data of the view and merged into reports using ODS or ODT (Open Document Standard Format Documents). When the data is used that way from a ViewModel, each tag in the document is replaced by a piece of information from the ViewModel's structure.
In general terms, the ViewModel unfolds a piece of your model and navigates through the different links and associations in your model to show some aspects of the application's data.
Rooted and Unrooted ViewModels
ViewModels come in two distinct ways/formats: that is, the rooted and the unrooted ViewModel.
- The unrooted ViewModels are used to find the data when the user is searching. They are called unrooted because they don't have a specific object in your database or model as their starting point. Instead, they are used to search or, in other ways, find objects by searching the database and showing that object or many objects in a list.
- The rooted ViewModels have a specific object as their starting point—for example, a person or something that is modelled specifically in your application. From that root object, the ViewModel, or the view, navigates through associations to show things related to the root object. Nothing prevents a rooted view from showing any object in the database, but it's usually an object associated somehow with the root object.
Parts of the ViewModel - Why are they called classes?
The ViewModel's different main parts are called ViewModel classes. Why "class"? You can think of the ViewModel as a definition of a new kind of object, each of which is a new kind of class. If you think of your model as being made up of classes that define attributes, the ViewModel, in the same way, defines new classes of information that are constructed out of pieces from your main model.
The green background is on the root ViewModel class.
The blue background indicates the ViewModel classes that are usually linked to the green root ViewModel class.
The blue ones all define collections of data.
Rooted vs Unrooted ViewModels + ValueStore
The un-rooted name of a ViewModel refers to whether the root ViewModel class has a root—so a lot of "roots" here. In this case, it means that if there is a main model object, that object is the context or self of the green view model root. In this case, you have "self" defined as an object in the main model. That is different from this example, where you don't have a root:
That means there is no "self" from the context of the ViewModel root class. In this example, you can see that Valuestore.allinstances is used. ValueStore is a class, and we can access all instances of that class in the database in the main model. By doing that, we get a collection of ValueStore objects that can be shown in the blue ViewModel class called ValueStore here. So the ValueStore ViewModel class has a context and, therefore, it has "self", as in the example above.
Use un-rooted view models to search or show a complete list of objects, or a partial list of objects, either just for showing or editing them. The classic use case is a Seeker in which the user can input a search term and use the database search features to find objects.
- Side note: the class of an unrooted ViewModel usually doesn't matter, but for ease of understanding from the developers' perspective, it's usually set to tell what this view is used for.
A rooted ViewModel is usually used to show some object properties from that object and related information. For example, in this example, we have viewed "one thing". The "thing" is a modelled class from the main model—we show some attributes and then we show a list of details. We follow that association from "self", which is a "thing", to "details".
So this evaluates to a collection of details, and the blue ViewModel class has a context of detail, shows attributes connected to that ViewModel class, and therefore to attributes of the main model detail objects that are in this list.
ViewModel class - Explained From a C# Perspective
As a side note, they can be generated into C# classes. You do this by selecting the Codegen checkbox.
Each of these will then be code generated and can then be used from C# as C# classes.
ViewModel classes from the perspective of C# traditional code would each be seen as an object with properties on it, and those properties would have a getter and setter that point to an object in the main model space. That way, when you read a property in a ViewModel class, you're actually reading from the backing object in your main model. When you're writing, the setter is executed and sets something in the main model—that is how it's implemented in the MDriven system. If you have an expression that creates a list of objects, that property is a list in the .net runtime that references other ViewModel objects that are objects of the other ViewModel class, which in turn has properties, and each of those properties is backed by another main model object.
Recurse, Cyclic UI
Even if the ViewModel graph is non cyclic you may want to build recursive trees of unbounded depth. You do this by pointing back to an existing nesting instead of creating a new; if your expression results in object or collection of object and you do not have "Associated to" set to a nesting - the Recurse picker will show - here you set the Nesting you want to loop back to. You should of course avoid producing graphs that never end.



