Eines der mächtigsten Features in Flex ist die Darstellung von Daten aus dem Model auf der GUI der Applikation per Data Binding. Wenn man Daten in einfachen Properties speichert und diese mit dem [Bindable]
Metatag versieht, wird ein daran gebundenes GUI-Element über einen Event von der Änderung benachrichtigt. Ist diese Property aber ein Array, bekommt eine daran gebundene Komponente nicht mit, wenn diesem Array ein Element hinzugefügt wird. Um einen Refresh der Liste zu bewirken, muß man manuell (z.B. innerhalb einer setter-Methode) ein myList.invalidateList()
vor der Änderung des Array-Inhalts ausführen. De Nachteil hierbei ist, daß man in der setter-Methode eine Referenz zu der darstellenden Listenkomponente halten muß. Das wiederspricht aber dem Prinzip der Trennung von Datenmodell und View.
Einzig der komplette Austausch des Arrays per var myArray = new Array()
würde eine selbständige Aktualisierung bewirken, da sich nun tatsächlich die Property geändert hat (und nicht nur der Inhalt des Arrays).
Um das einfach zu umgehen, kann man statt eines Arrays eine ArrayCollection benutzen. Fügt man einer ArrayCollection mit myArrayCollection.addItem()
ein Element hinzu, wird auch eine daran gebundene Komponente aktualisiert.
Beispiel:
Databinding Demo
Beispielcode (Flex MXML):
Das Beispiel zeigt 2 Listen, die bei jedem Klick um einen Eintrag erweitert werden.
Die erste Liste ist an ein Array gebunden und wird aktualisiert, indem Sie über die Methode addItem()
jeweils dezidiert invalidiert wird.
Die zweite Liste zeigt, wie mit Hilfe der Bindung an eine ArrayCollection diese Aktualisierung automatisch erfolgt, ohne, daß man speziell die darstellenden List-Komponente kennen muss.
Ich habe gerade eine GUI programmiert, die über Data-Binding das Array einer anderen Klasse als Data-Provider für sein Data-Grid benutzt. Wird das Array aktualisiert, aktualisiert sich automatisch auch die GUI.
Ist der von Dir beschriebene „Fehler“ seit Februar vielleicht beseitigt worden?
Prinzipiell wird eine automatische Aktualisierung auch dann stattfinden, wenn du den Inhalt des Arrays über eine Zuweisung änderst. Beispiel:
array_A
ist an eine Listkomponente gebunden. Du erzeugst über eine Operation ein neues Arrayarray_B
mit neuen Inhalten. Mitarray_A = array_B
weist du dann die Inhaltearray_A
zu und deine Liste wird automatisch aktualisiert. Das ist normal, da dann der Changewatcher tatsächlich eine Änderung der Objektreferenz wahrnimmt und einen entsprechenden Changeevent wirft.Ein anderes Problem wird dabei aber auftreten – welches aber nicht unbedingt relevant für deine Anwendung sein muss: ein zuvor selektiertes Element in der Listenkomponente wird anschließend wieder deselektiert sein. Das lässt sich durch Verwendung einer ArrayCollection auch vermeiden.
Hm, dieses Szenario habe ich tatsächlich nicht. Ich stelle im Moment nur die Gesamtheit aller Daten dar und lasse (noch) keine Auswahl einzelner Elemente zu.
Sollte ich das mal einbauen wollen, bin ich aber schonmal froh, frühzeitig auf dieses Problem hingewiesen worden zu sein.
Vielen Dank 😉
Gut, dass ich mich an diesen Eintrag erinnert habe – jetzt habe ich das mit der „sich selbst aktualisierenden“ ArrayCollection doch gebraucht 😉