6.4 Synchronization Between Model and View
Automatic synchronization between Model and View is controlled by the .dataoptions[] attribute.
Table 16-6: Options for synchronization between Model and View
Attribute Index |
Default |
Component |
Meaning |
---|---|---|---|
true |
View |
Immediately before the View is made visible, the data values are fetched from the Model components and set on the View object. |
|
false |
View |
During object initialization (:init method), the data values are retrieved and set on the View object. |
|
false |
View |
Immediately before the View is made invisible, the data values are fetched from the View object and assigned to the linked Model components. |
|
false |
View |
If a user interaction triggers a dialog event which indicates a possible change of a View attribute, this is assigned to the linked Model components. |
|
true |
Model |
When a dialog or module is started, the data from the Model objects is forwarded to the linked View components. |
|
true |
Model |
Modifications to a Model attribute are forwarded to the linked View components. |
|
true |
Model |
This index value is only available for the doccursor. |
A key feature of the Datamodel is that data changes are always signaled and processed asynchronously
via the event processing. For example, if the Data Model (Model object) is a record or another object with user-defined or predefined attributes, an attribute change, which is signaled by a datachanged event, is transmitted to the linked View objects so that they can update themselves. The dialog programmer can suppress a changed event with the operation ::=
, but never a datachanged event.
A global variable may be used as a Model component as well, but does not allow controlling the synchronization. Variable values s are always propagated when the dialog or module is started and when the variable value is changed.
When .dataoptions[dopt_apply_on_unmap] := true; is used on a dialogbox, messagebox or filereq via a querybox call, the data values are only transferred from the View to the Model in case of a positive confirmation (button_ok or button_yes).
Manual intervention is not necessary in most cases. However if required, manual synchronization can be accomplished using the following methods:
Table 16-7: Manually callable Datamodel methods
Method |
Component |
Function |
---|---|---|
:represent() |
View |
The data of all linked Model attributes (.dataget) is retrieved and assigned to the View object |
:apply() |
View |
The data from all linked View attributes (.dataset) is fetched and assigned to the Models |
:propagate() |
Model |
The Model object communicates a change of all its Model attributes to the View objects that have a linkage. |
:collect() |
Model |
The Model object fetches all data from the linked View objects to assign it to its Model attributes. |
Synchronization only happens between instances, never with Default objects or Models.
For optimized synchronization of partial values, there is another particular feature. If a value change is signaled, the index of this value change is forwarded so that only this single value needs to be updated by the View component.
Example
Through a timer object, random colors are picked and assigned to random table cells.
dialog D color CoRed "red"; color CoYellow "yellow"; color CoGreen "green"; color CoBlue "blue"; timer TiRandomColors { .active true; .starttime "+00:00:00"; .incrtime "+00:00:00'100"; object Color[index] := null; on select { variable index RandIndex := [1 + random(5),1 + random(5)]; variable object RandColor := D.color[1 + random(D.count[.color])]; /* change the color at a specific index */ this.Color[RandIndex] := RandColor; } } window Wi { .title "Datamodel - random colors"; .width 400; .height 400; tablefield Tf { .xauto 0; .yauto 0; .rowcount 5; .colcount 5; .colwidth[0] 60; .rowheight[0] 30; .dataoptions[dopt_represent_on_map] false; /* avoid initial :represent() */ .datamodel TiRandomColors; .dataget[.bgc] .Color; } }
This is the screenshot for it: