Verbesserung
Top-Thema
Detail
Wichtig
Detail
Top-Thema
#26311
GridComponent: Programmatische Invalidierung nach Multiselektion führt zu undefiniertem Verhalten
Bei Benutzung der GridComponent zur tabellarischen Darstellung von persistenten Objekten und der eingeschalteten Multiselektion (über die Checkbox-Spalte) kann ein Zustand herbeigeführt werden, bei dem das innere GUI-Modell der Komponente inkonsistent wird und somit zu einem undefinierten Verhalten führt. Das Szenario hierfür ist wie folgt:
- Selektiere mehrere Zeilen in der GridComponent über die Checkbox-Spalte
- Invalidiere die Komponente programmatisch (über GridComponent.invalidate()) mithilfe z.B. eines Buttons.
- Selektiere eine zusätzliche Zeile
=> Es wird eine ClassCastException geworfen und die Selektion entspricht nicht der erwarteten, sondern es werden teilweise vollkommen andere Zeilen selektiert oder plötzlich gar nichts.
=== Analyse In com.top_logic.element.layout.grid.AbstractGridHandler.selectionToFormGroups(Object) werden nur Sets korrekt behandelt. Nach der programmatischen Invalidierung allerdings scheint die Selektion in Form einer Liste vorzuliegen. Das führt u.a. auch dazu, dass das serverseitige GUI-Modell (die FormGroups) fehlerhaft annotiert wird, sodass ein und dieselbe Zeile mit mehreren Fachobjekten unter GridComponent.PROP_ATTRIBUTED versehen wird.
Versucht man nun - basierend auf der Selektion - Fachcode auszuführen, so wird der Fachcode auf vollkommen falschen Objekten ausgeführt.
Verbesserung
Im Zuge von #24566 wurden einige Verbesserungen an der Gridselektion vorgenommen, die dazu geführt haben, dass Selektionen plötzlich als Listen und nicht als Sets eingespeichert werden. Da das Programm dafür nicht ausgelegt ist führt das zu dem beschriebenen Verhalten. Um die Selektion wieder als Set zu speichern wurde der Rückgabewert von com.top_logic.element.layout.grid.GridUtil.getBusinessObjectsFromInternalRows(Collection<?>) (und alle darin aufgerufenen Methoden) von List zu LinkedHashSet geändert.
Test
**Auf TL_6x:** Eine Sicht mit Grid erstellen, die eine Multiselektion unterstützt. Alternativ kann auch einfach diese Sicht genutzt werden: Technische Demo > Tests > Externe Selektion > Externe Selektion in Grid. Zusätzlich muss noch ein Button zum Invalidieren eingefügt werden. Um Grid oben links anzupassen muss in gridExternalSelection.xml in der Grid mit Namen "gridDemo1" noch folgendes eingefügt werden: {{{#!xml <buttons>
<reference command-id="invalidate"/>
</buttons> }}} Jetzt die Anwendung starten und in die entsprechende Sicht wechseln. In der angepassten Grid einige Zeilen selektieren und dann auf den neu eingefügten invalidate Button klicken. Die Selektion muss erhalten bleiben und es darf keine Fehlermeldung entstehen. Auch weitere Selektionen dürfen keine Fehlermeldungen erzeugen und müssen funktionieren.
**Auf TL_7x** Da die entsprechenden Funktionen hier nicht verwendet werden hier noch ein Refactoring.