You can use actions in MDriven Designer to open a ViewModel, pass the selected object into a detail view, and build browser-to-detail navigation as your model grows.
What actions do
An action is an operation that can be presented to the user and can open a ViewModel. For navigation, configure the action to state:
- which ViewModel to open; and
- which root object, if the target ViewModel is rooted.
A rooted ViewModel is a ViewModel that works with one specific object as its root. For example, a Class1 Object View can show and edit the attributes of one Class1 object. A browser that lists every Class1 object does not need a single root object.
For the wider role of actions in an application, see Documentation:Application actions. For action naming and the difference between an action name and its presentation text, see Training:Action names.
The following example uses a model class named Class1. It creates a browser that lists all instances, lets the user create an instance, and opens the selected instance in a detail ViewModel.
Create the detail ViewModel
- Add a ViewModel for one
Class1object. For example, name itClass1 Object View. - Set its type to
Class1. - Mark the ViewModel as requiring a root object.
- Add the attributes you want to edit or display, such as
Attribute1.
This ViewModel must receive a Class1 object when it opens. It is not a useful entry point by itself unless an action supplies a root object or the root is changed in the designer by dragging an object to the root dot.
Create the browser ViewModel
- Add a ViewModel and name it
BrowserView. - Set its type to
Class1. - Add a nested ViewModel class for the list.
- Set the nested ViewModel expression to
Class1.allInstances. - Add the columns that identify each item. For example, show
Attribute1.
BrowserView displays a collection, so it does not require a root object. It is a suitable view to open from a main menu or other global entry point.
Add an entry action for the browser
- Select
BrowserView. - Add a global action for Show.
- Refresh the model.
- Run the application and invoke the resulting action, such as
Show BrowserView.
The browser action opens BrowserView without a root object because the list expression already obtains all Class1 instances.
Add a create action in the browser
- Open the action definitions while working with
BrowserView. - Add a ViewModel action that evaluates
Class1.create. - Refresh the model.
- Open
BrowserViewand invoke the new action to create an item.
Action definitions are filtered for the ViewModel you are working on and the matching class actions. This helps reduce the number of actions shown when a model contains many actions.
Open the selected item in the detail ViewModel
- Create or select a class action in the context of a
Class1item in the browser list. - Set the action's target ViewModel to
Class1 Object View. - Set the action's root object expression to
self. - Refresh the model.
- In the browser, select an item and invoke the action.
In this example, self is the selected Class1 object. The action opens Class1 Object View with that object as its root, so edits in the detail view affect the same object shown in the browser.
| Navigation situation | Target ViewModel | Root object expression |
|---|---|---|
| Show all objects | BrowserView
|
None. The nested list uses Class1.allInstances.
|
| Show the selected object | Class1 Object View
|
self, evaluated in the selected Class1 context.
|
| Open a newly created object | Class1 Object View
|
Class1.create, which creates the object and uses the result as the root.
|
Root object expressions
The root object expression determines the object supplied to a rooted target ViewModel when the action runs. Use it whenever an action opens a ViewModel that requires a root object.
For example, an action that opens Class1 Object View can use:
selfWhen the action is a class action for Class1, this passes the current Class1 instance into the target ViewModel.
To open a detail ViewModel for a new object, use:
Class1.createThe expression result becomes the target ViewModel root. After a model refresh, the new root is available to the view.
Match the action to the ViewModel requirement
Keep the target ViewModel configuration and the action configuration consistent:
- If an action sets a root object, the target ViewModel should be marked as requiring a root object.
- If a ViewModel displays a collection and does not need one root object, do not configure its global entry action to set one.
Model checking reports a warning when a global action sets a ViewModel root object but the target ViewModel is not marked as requiring a root object. Set the requirement on the target ViewModel, then check the model again to remove the mismatch.
Execute expression on show
An action can also have an execute expression on show. MDriven evaluates this expression whenever the target view is shown. It is useful for setting state or context when the view opens; it does not replace the root object expression.
For example, when a class action opens a rooted Class1 Object View, the receiver's root can be represented by a variable such as vCurrentClass1ObjectView. The calling action context is available through vSender. If the action's execute expression on show changes an attribute, showing the view repeatedly repeats that change.
Attribute1 := Attribute1 + 1If Attribute1 starts empty and the view is shown, it can become 1; showing the same view again can change it to 11. Use this behavior deliberately. Use the root object expression to select the object the view works with, and use execute expression on show for work that must happen each time the view opens.
Navigation becomes harder to follow as you add ViewModels and actions. Use the Action Navigations and ViewModels overview in MDriven Designer to see the available ViewModels and the actions that open them in one place. This is especially useful when several actions lead to the same view or when a view can navigate onward to related views.
For guidance on that overview, see Documentation:Actions And Viewmodels, MDriven Designer.
Common patterns and gotchas
| Situation | Use this pattern | Watch for |
|---|---|---|
| Main entry to a list | A global Show action that opens a browser ViewModel with a collection expression such as Class1.allInstances.
|
Do not set a root object when the browser does not require one. |
| List item to detail view | A class action with target ViewModel Class1 Object View and root object expression self.
|
Mark the detail ViewModel as requiring a root object. |
| Create then edit | Use Class1.create as the root object expression for the detail ViewModel, or create in the browser and navigate from the created item.
|
Confirm that the expression result has the type expected by the target ViewModel. |
| Initialization each time a view opens | Put the initialization in execute expression on show. | This runs on every show and is not a substitute for setting the root. |
