In folgender Situation kommt es zu einem Javascript-Fehler:
Zwei Tabellen X` und `Y sind sichtbar. Y ist eine Tree-Table die als Drop-Target definiert ist.
Jetzt gibt es jetzt einen Event der dafür sorgt, dass X` die Selektion ändert und `Y den Aufklappzustand eines Knotens.
Dann gibt es dem Javascript-Fehler:
2021-03-30 10:50:15,149 ERROR [qtp1638335699-46]: base.services.simpleajax.AJAXServlet$AJAXLogHandler - Client-side message: Uncaught JavaScript exception (exception: 'TypeError: nodesArray is null', component: 'masterFrame', source: 'http://localhost:8080/pvm/servlet/LayoutServlet/w19502b3c85120aaa-f8697ac5a0fdad1', layout: 'masterFrame.xml', session: node01330x7z95lzb618k37obsjewrs2, UserAgent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0])
Ursache
Die Tree-Table Y zeichnet sich neu, da der Aufklappzustand eines Knotens geändert wird.
Y` ist Drop-Target, deswegen ist der HTML-Dom-Parent `D der Tabelle ein DIV ohne ID (der tl:ContentRenderer schreibt ein anonymes DIV) welches neu gelayoutet wird.
Weil X auch ein Update hat gibt es 2 Knoten die gelayoutet werden müssen.
Jetzt gibt es Javascript-Code der die Menge der zu layoutenden Knoten M` analysiert um nur Knoten zu layouten, die keine inneren zu layoutenden Knoten haben. Dazu wird geschaut, ob es zu einem Knoten in `M einen DOM-Vorfahren in M` gibt. Dies wird gemacht indem geschaut wird ob es zu einem Vorfahren einen Knoten in `M mit der selben ID gibt.
In M` ist das anonyme DIV (ohne ID) `D enthalten das vom tl:ContentRenderer geschrieben wurde. Natürlich gibt es einen Vorgänger dieses DIV's mit der selben, nämlich keiner, ID. Der Algorithmus denkt es gibt einen Ancestor in M` und ignoriert `D. Alle anderen zu layouten Knoten werden ebenfalls vom Algorithmus als Kind von D angesehen, also ignoriert.
Die Folge ist, das (vermeintlich) keine Knoten gelayoutet werden müssen. Jetzt schlägt ein Fehler in der LinkedHashMap (in JS) zu der sagt: Die Werte einer leeren Map sind null. So findet ein null Zugriff statt.
Test
- Ein automatischer Test ist nicht möglich, da das Problem im JavaScript Code liegt.
- Da das Problem sonst nur mit zusätzlichen Sichten reproduziert werden kann, die technisch aber nicht sinnvoll sind, muss ein Patch eingespielt werden.
- Folgenden Patch einspielen:
{{{#!patch ### Eclipse Workspace Patch 1.0 #P com.top_logic Index: src/com/top_logic/layout/layoutRenderer/ContentRenderer.java =================================================================== --- src/com/top_logic/layout/layoutRenderer/ContentRenderer.java (revision 307602) +++ src/com/top_logic/layout/layoutRenderer/ContentRenderer.java (working copy) @@ -94,7 +94,7 @@ businessComponent.writeDebugHeader(out); }
- if (dropEnabled(contentControl)) {
+ if (true || dropEnabled(contentControl)) { out.beginBeginTag(DIV); out.beginCssClasses(); out.append("lcViewport"); }}}
- Im Demo in der DemoTypes Struktur unter dem Wurzel Knoten zwei Knoten generieren lassen.
- In folgende Sicht gehen: Technisches Demo > Layout-Framework#1 > Formulare > In-App Drag and Drop
- In der TreeGrid den ersten der generierten Knoten aufklappen und das A1 in die TreeTable auf den zweiten generierten Knoten ziehen.
- Es darf kein Error geloggt werden.
- Alle angezeigten Sichten müssen korrekt aussehen.
- Insbesondere muss in allen angezeigten Tabellen die Fußzeile unten angezeigt werden und nicht irgendwo rechts oben direkt unter dem Tabellen-Header neben den Spalten-Inhalten.