enhancement
major
minor
defect
critical
major
minor
major
#30045
Ebenen-Slots anzeigen: Bericht über „ <slot-content> “, das „no <slot> “ erreicht, leeres Fallback von „ <slot> “, Slot-Positionen in geteilten Fenstern und in der Seitenleiste
Folge zu #29767. Siehe auch: #29108 (Einführung von <slot> / <slot-content>).
<slot-content to="X"> (SlotContentElement, Paket com.top_logic.layout.view.slot) deklariert den Inhalt einer Ansicht, der am nächstgelegenen <slot name="X"/> (SlotElement) des Elementbaums angezeigt wird; SlotRegistry leitet jeden Beitrag an den gleichnamigen Platzhalter mit der geringsten Baumdistanz (SlotPath.distance) weiter. Der Entwicklerartikel „view-layer/layout“ (Abschnitt „In einer umschließenden Region angezeigter Inhalt“) beschreibt dies. Es bleiben drei Lücken.
1. Ein Beitrag ohne Slot verschwindet unbemerkt
SlotRegistry.reroute() überspringt einen Beitrag, für den findNearest keinen Platzhalter findet: Sein Inhalt wird nirgendwo angezeigt und es wird nichts gemeldet. Ein falsch geschriebener „to“-Parameter oder eine in einer Shell ohne den Slot verwendete Ansicht sieht wie ein Darstellungsfehler aus.
Behebung: Melden Sie einen Beitrag, der nicht weitergeleitet wird. Da sich die Weiterleitung ändert, während Platzhalter angefügt und entfernt werden (ein Slot in einem Dialog oder eine verzögert erstellte Registerkarte kann später erscheinen), melden Sie dies, sobald die Interaktion, durch die er angefügt wurde, abgeschlossen ist (z. B. wenn sich der „DeliveryScope“ stabilisiert), als Warnung im Protokoll unter Angabe des Slot-Namens und der Ansichtsquelle des Beitrags sowie als Diagnose des SlotContentControl (putDiagnostic("unrouted", true)), damit der UI-Inspector dies anzeigt. Ein Attribut optional="true" bei <slot-content> unterdrückt die Warnung für Inhalte, die nur dort angezeigt werden sollen, wo eine Shell den Slot anbietet.
Test: Unit-Test für SlotRegistry (neben TestSlotUrlAdoption): Ein Beitrag mit unbekanntem Namen wird gemeldet, einer, dessen Slot in derselben Interaktion angehängt wird, nicht; einer mit „optional=“true““ wird ebenfalls nicht gemeldet.
2. Kein Fallback für einen leeren Slot
SlotElement hat nur einen Namen; ein Slot ohne Beiträge rendert nichts. Ein Bereich, der standardmäßig etwas anzeigen soll (ein Standardtitel in „appbar-content“, ein Hinweis „keine Aktionen“ in einer Fußzeile), benötigt den Inhalt in jeder beitragenden Ansicht.
Lösung: Eine optionale <empty> -Liste von UI-Elementen unter <slot>, die im Kontext der deklarierenden Ansicht erstellt und angezeigt wird, solange kein Beitrag an den Slot weitergeleitet wird (SlotPlaceholderControl.setRoutedContributions wechselt zwischen den weitergeleiteten Steuerelementen und dem Fallback).
Test: Eine Ansicht mit <slot name="x"><empty><text .../></empty></slot> zeigt den Text an; nachdem ein <slot-content to="x"> angezeigt wurde, wird nur noch der Beitrag angezeigt, und der Text erscheint wieder, sobald der Beitrag die Anzeige verlässt.
3. Fenster in geteilten Bereichen und Seitenleistenelemente teilen sich eine Slot-Position
Container erweitern den Slot-Pfad ihrer untergeordneten Elemente über ` ViewContext.withChildSlotPath(...) ` (ContainerElement, ColumnsElement, AppBarElement, ContentSection für Registerkarten und Akkordeon-Abschnitte, ReactSwitchControl, ReactWizardControl, …). SplitPanelElement und SidebarElement tun dies nicht, sodass alle Bereiche eines geteilten Fensters (und alle Elemente einer Seitenleiste) dieselbe Position haben. Zwei Slots mit demselben Namen in zwei Bereichen befinden sich dann gleich weit von einem Beitrag entfernt, und der zuerst registrierte Slot hat Vorrang (findNearest verwendet ein striktes <), unabhängig davon, wo sich der Beitrag befindet.
Lösung: Erweitere den Slot-Pfad pro Bereich (um die Bereichs -ID oder den Index) in `SplitPanelElement` und pro Element in `SidebarElement`, so wie es `ContentSection` mit der Registerkarten-ID tut; entferne dann die entsprechende Problemstelle aus dem Artikel „view-layer/layout“.
Test: Ein geteiltes Panel mit einem <slot name="x"/> und einem <slot-content to="x"> in jedem der beiden Bereiche: Jeder Beitrag wird im Slot seines eigenen Bereichs angezeigt.
4. Ein Slot zeigt für einen Moment alte und neue Inhalte gleichzeitig an
Ein Container, der seinen Inhalt wechselt, fügt den neuen Inhalt hinzu, bevor er den alten entfernt (ReactWizardControl.displayCurrentStep, ebenso <switch>, Registerkarten, Sidebar-Elemente, Frames). Da die Registry bei jeder Registrierung umgeleitet wurde, erhielt der Slot zwei Aktualisierungen in einer Interaktion – zunächst alte und neue Beiträge zusammen, dann nur die neuen – und der Browser zeichnete den Zwischenzustand für einen Frame: Die Schaltflächen des verlassenen und des betretenen Schritts standen nebeneinander in der Fußzeile des Assistenten.
Lösung
- Hook „End-of-Interaction“: DeliveryScope.afterInteraction(Runnable) (com.top_logic.layout.react) führt die Arbeit einmal aus, wenn die äußerste Interaktion des Threads abgeschlossen ist, während der Bereich noch offen ist und bevor dessen Aktualisierungen ausgeliefert werden, sodass die durch die Arbeit vorgenommenen Änderungen mit der Interaktion ausgegeben werden; Auch während der Ausführung registrierte Aufgaben werden ausgeführt; ein fehlgeschlagenes Arbeitselement wird protokolliert, ohne den Rest oder die Übermittlung zu unterbrechen. Außerhalb einer Interaktion werden die Aufgaben sofort ausgeführt. DeliveryScope.isOpen() gibt an, ob eine Interaktion offen ist.
- Routing einmal pro Interaktion: Eine Registrierung oder Abmeldung eines Slots oder eines Beitrags markiert das Routing lediglich als ausstehend; SlotRegistry berechnet sie einmalig, wenn die Interaktion abgeschlossen ist, und ein Slot, der kurz vor dem Schreiben steht, schließt sie zunächst ab (SlotRegistry.settleRouting() aus SlotPlaceholderControl.onBeforeWrite()), sodass eine Seite mit ausgefüllten Slots geschrieben wird und ein Slot in einem einzigen Update von den alten zu den neuen Beiträgen wechselt. Außerhalb einer Interaktion wird die Zuordnung sofort berechnet.
- Meldung eines nicht zugewiesenen Beitrags: Im selben Durchlauf am Ende der Interaktion wird jeder Beitrag, der keinen Slot erreicht und nicht optional ist, mit der Diagnose „unrouted“ gekennzeichnet (wird im UI-Inspector angezeigt), und eine Warnung nennt den Slot sowie den Konfigurationsort des <slot-content>. Ein Beitrag wird einmal gemeldet, solange er ohne Slot bleibt, und erneut erst, nachdem ein Slot ihn zwischendurch erfasst hat; sobald er geroutet ist, verliert er die Markierung. Außerhalb einer Interaktion wird nichts überprüft (eine endende Sitzung baut ihre Bäume ohne Überprüfung ab, wobei ihre Slots die Anzeige vor den Beiträgen verlassen). Das Umschalten der Schublade, das eine <sidebar> in den mit „drawer-open-slot-name“ benannten Slot einfügt, wird auf dieselbe Weise gemeldet, da die kompakte Schublade ohne den Slot nicht geöffnet werden kann.
- optional on <slot-content> (SlotContribution.isOptional()) unterdrückt die Meldung für Inhalte, die nur für Shells bestimmt sind, die den Slot anbieten.
- <empty> bei <slot>: Elemente, die im Kontext der deklarierenden Ansicht erstellt werden (Slot-Pfadsegment leer), die dem Platzhalter gehören, angezeigt werden, solange kein Beitrag an sie weitergeleitet wird, abgetrennt werden, sobald ein Beitrag sie überdeckt, und zusammen mit dem Slot entsorgt werden. Die Slots der App-Leiste der Shell haben die IDs „appbar-leading“ und „appbar-content“, sodass eine Anwendung „appbar-content“ einen Standardwert mit einem Overlay von „app.view.xml“ zuweisen kann (<slot config:ref="appbar-content"><empty>...); die mitgelieferte Shell zeigt keinen Standardwert an.
- Slot-Pfade: „SplitPanelElement“ erweitert den Slot-Pfad pro Bereich ( Bereichs-ID, andernfalls Index), „SidebarElement“ pro Element (Element-ID) sowie für die Kopf- und Fußzeile der Leiste.
- Demo: Die Assistenten-Demo von tl-demo-react zeigt während des automatisch fortlaufenden Schritts ohne Schaltflächen einen Hinweis im Fußzeilen-Slot an; die Zurück-Schaltfläche der ersten Frage führt an diesem Schritt vorbei zum Profil, da ein erneut aufgerufener Schritt wartet, anstatt fortzufahren.
- Die Artikel „view-layer/layout“ und „view-layer/app-shell“ beschreiben optionale Elemente, <empty>, den Bericht, das Routing am Ende einer Interaktion sowie die Slot-IDs; die Fallstricke bezüglich des stillen Beitrags und der gemeinsamen Position von Fenstern/Seitenleistenelementen wurden beseitigt.