6.4 Synchronisierung zwischen Model und View
Die automatische Synchronisierung zwischen Model und View wird über das .dataoptions[]-Attribut gesteuert.
Tabelle 19-8: Optionen zur Synchronisierung zwischen Model und View
Attribut-Index |
Standard |
Komponente |
Bedeutung |
---|---|---|---|
true |
View |
Direkt vor der Sichtbarschaltung werden von den Model-Komponenten die Datenwerte geholt und dem View-Objekt gesetzt. |
|
false |
View |
In der Objektinitialisierung (:init-Methode) werden die Datenwerte geholt und am View-Objekt gesetzt. |
|
false |
View |
Direkt vor der Unsichtbarschaltung werden die Datenwerte vom View-Objekt geholt und den gekoppelten Model-Komponenten zugewiesen. |
|
false |
View |
Wird durch eine Benutzerinteraktion ein Dialogereignis erzeugt, welches auf eine mögliche Änderung eines View-Attributs hinweist, so wird dieses den gekoppelten Model-Komponenten zugewiesen. |
|
true |
Model |
Beim Start des Dialogs bzw. Moduls werden die Daten der Model-Objekte an die gekoppelten View-Komponenten weitergegeben. |
|
true |
Model |
Änderungen an einem Model-Attribut werden an die gekoppelten View-Komponenten weitergereicht. |
|
true |
Model |
Dieser Indexwert ist nur für den doccursor verfügbar. |
Ein ganz wichtiges Merkmal des Datenmodells ist, dass Datenänderungen immer asynchron
über die Ereignisverarbeitung gemeldet und abgearbeitet werden. Ist z.B. das Datenmodell (Model-Objekt) ein Record bzw. ein anderes Objekt mit benutzerdefinierten oder vordefinierten Attributen, so wird eine Attributänderung, die über ein datachanged-Ereignis signalisiert wird, an die verbundenen View-Objekte gemeldet damit diese sich aktualisieren können. Der Dialogprogrammierer kann zwar über die Operation ::=
ein changed-Ereignis unterbinden, niemals aber ein datachanged-Ereignis.
Eine globale Variable kann ebenso als Model-Komponente verwendet werden, erlaubt aber keine Steuerung der Synchronisation. Es erfolgt bei Variablen immer eine Wertepropagierung bei Start des Dialogs bzw. Moduls und bei Änderung des Variablenwertes.
Wird .dataoptions[dopt_apply_on_unmap] := true; an einer Dialogbox, Messagebox oder Filereq über einen querybox-Aufruf genutzt, so erfolgt die Übertragung der Datenwerte von der View zum Model nur bei einer positiven Bestätigung (button_ok oder button_yes).
Ein manueller Eingriff ist in den meisten Fällen nicht notwendig. Falls doch erforderlich, kann eine manuelle Synchronisation über die folgenden Methoden passieren:
Tabelle 19-9: Manuell aufrufbare Datenmodellmethoden
Method |
Komponente |
Funktion |
---|---|---|
:represent() |
View |
Die Daten aller gekoppelten Model-Attribute (.dataget) werden geholt und dem View-Objekt zugewiesen |
:apply() |
View |
Für alle gekoppelten View-Attribute (.dataset) werden die Daten geholt und den Models zugewiesen |
:propagate() |
Model |
Das Model-Objekt propagiert eine Änderung aller seiner Model-Attribute an die View-Objekte, die eine Kopplung aufweisen |
:collect() |
Model |
Das Model-Objekt holt sich alle Daten aus den gekoppelten View-Objekten um sie seinen Model-Attributen zuzuweisen |
Eine Synchronisierung findet nur zwischen Instanzen statt, niemals mit Default-Objekten oder Modellen.
Für eine optimierte Synchronisation von Teilwerten gibt es noch eine weitere Besonderheit. Wird eine Wertänderung signalisiert so wird der Index dieser Wertänderung weitergeleitet sodass nur dieser Einzelwert von der View-Komponente zu aktualisieren ist.
Beispiel
Über ein Timer-Objekt werden zufällige Farben ausgewählt und zufälligen Zellen einer Tabelle zugeordnet.
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; } }
Bildschirmfoto dazu: