Super. Es funktioniert, auch wenn man eben ein globales Script braucht, da ja dem nichtnachgeladenen Backend-Rahmen nicht bekannt ist, was alles so nachgeladen werden könnte. Alternativ müsste man nachgeladene Scripte nach dem Laden aktiv "restarten".
Und es funktioniert sowohl für das "alte" als auch das "neue" Backend.
Ich denke, dies ist aber nun die bessere/sauberere Lösung:
1. Im XLabel Callback baue ich ein Daten-Element ein (nicht mehr das Script selbst), was die Variablen an das zentrale Javascript übergibt und nebenbei als Kenner fungiert, dass hier was "Eigenes" vorhanden ist.
Code:
return <<<EOT
<span id="myapp-callback1-data" class="myapp-data"
data-myvalue="$myValue"
data-myimage='$myImage'>
</span>
EOT;
Dabei ist darauf zu achten, dass das Dataset im Javascript nachher die Benennung ausschließlich in Kleinbuchstaben ausführt: dataspan.dataset.data-myvalue. Auch die Anführungszeichen sind zu beachten, da $myImage hier als HTML mit ""-Eigenschaften ausgeführt ist.
2. Es gibt ein zentrales Javascript, was insbesondere das grundlegende Event-Handling und praktikablerweise auch die Callback(s) ausführt:
Code:
(function() {
document.addEventListener('DOMContentLoaded', () => {
document.addEventListener('myapp:loaded', () => {
if (document.querySelector('.myapp-data')) {
MyCallback1();
// ...
}
});
const e = new CustomEvent('myapp:loaded');
if (window.Turbo) {
document.addEventListener('turbo:load', () => {
document.dispatchEvent(e);
})
}
document.dispatchEvent(e);
});
function MyCallback1() {
//...
}
// ...
})()
Das Nachladen von Komponenten im Backend erfolgt über den Frame-Handler Turbo. Der Bereich mit dem Tag <turbo-frame> wird bei jedem Seitenwechsel aktualisiert.
Der Abschluss des Nachladen eines Frames wird durch das Event turbo:load angezeigt. Die Prüfung, ob Turbo vorhanden ist könnte gegebenenfalls auch entfallen. Andere Event-Handler von Turbo sind nicht erforderlich. Normale MutationObserver auf <body> oder <turbo-frame> funktionieren gar nicht oder nur beim ersten Nachladen.
3. Das zentrale Javascript wird beispielsweise in der config/config.php der Erweiterung eingebunden.
Code:
$GLOBALS['TL_JAVASCRIPT'][] = 'bundles/myapp/be.js';
Ein Einbinden in den Javascript-Bereich der Erweiterung ($GLOBALS['BE_MOD']['content']['myapp'] = ['javascript' => ...]) funktioniert nicht, da das Javascript dann nur aufgerufen wird, wenn die Seite der Erweiterung selbst beim ersten Laden des Backends die aktive Seite ist. Startet man mit einer anderen Backend-Seite und wechselt dann auf die Seite der Erweiterung, wird ja nur deren Frame-Inhalt nachgeladen und das Javascript der Erweiterung selbst verbleibt unberücksichtigt.