Umwandlung von Modals von Legacy-Controllern in die neue DModal Component API

:information_source: Wenn Sie ein neues Modal implementieren, schauen Sie sich die Hauptdokumentation hier an. Dieses Thema beschreibt, wie man ein bestehendes controller-basiertes Modal auf die neue komponentenbasierte API migriert.

Früher verwendete Discourse eine auf Ember-Controllern basierende API zum Rendern von Modals. Um das Modal aufzurufen, übergaben Sie einen String mit dem Namen des Controllers an showModal(). Im Hintergrund wurde dabei die Ember-API Route#renderTemplate verwendet, die in Ember 3.x veraltet ist und in Ember 4.x entfernt wird.

Um Discourse ein Upgrade auf Ember 4.x und höher zu ermöglichen, haben wir eine neue komponentenbasierte API für Modals eingeführt. Diese neue API nutzt die „deklarativen

20 „Gefällt mir“

Das sieht wirklich großartig aus. Es gibt mir Hoffnung, dass ich meine Modals auf Ember 4 umstellen kann. Ich verstehe den Ember-Code, den ich schreibe, nur kaum, daher ist es nicht einfach, Dokumentationen zu schreiben, die ich verstehen kann. Vielen Dank dafür.

8 „Gefällt mir“

Danke für das Tutorial! Die Beispiele waren sehr hilfreich. Ich konnte mein benutzerdefiniertes Plugin-Modal in einer Stunde reparieren.

4 „Gefällt mir“

Ich arbeite gerade an dieser Konvertierung, stoße aber auf ein Problem:

Zuvor hatte unser Modal keine entsprechende Controller-/JS-Definition und wir konnten das Modal über showModal($HBS_FILE_NAME) anzeigen. Da das neue show() eine Komponente benötigt, muss ich diese JS-Definition einführen (ist das eine korrekte Annahme?).

Ich habe etwas hinzugefügt wie:

import Component from '@glimmer/component';

export default class SomeModal extends Component {

  constructor() {
    super(...arguments);
    console.log('Modal constructor')
  }
}

und die vorherige .hbs-Datei (mit erforderlichen Änderungen an DModal) sowohl im Verzeichnis /components/modal als auch mit demselben Dateinamen. Wenn ich versuche, das Modal zu rendern (über getOwner(this).lookup("service:modal").show(SomeModal)), sehe ich, dass mein Konstruktor-Log in der Konsole ausgegeben wird, aber das Modal wird nicht gerendert.

Ist eine weitere Konfiguration im Controller/in der JS-Definition für diese Änderung erforderlich? Jeder Hinweis wäre sehr willkommen!

Sie benötigen sie nicht, wenn Sie keinen Code hinzufügen.

Sie können einfach die .hbs-Datei haben.

discourse-templates zum Beispiel hat keine entsprechende JS-Datei für die Modal-Handlebars-Vorlage.

Haben Sie Ihre Handlebars-Vorlage gemäß den Anweisungen angepasst?

Gibt es Fehler in der Konsole?

2 „Gefällt mir“

Danke für das Feedback! Riesiges :facepalm: von meiner Seite, ich hatte die Dateien in das Verzeichnis .../discourse/templates/components/modal verschoben, anstatt nach .../discourse/components/modal. Jetzt funktioniert alles wie erwartet (mit oder ohne den .js-Controller), danke!

3 „Gefällt mir“

Könnten Sie mir zeigen, wie ich showModal() aus einem Skript in einer head_tag.html-Datei aufrufen kann? In meinem Fall muss ich verwenden

document.querySelector(".actions .double-button .toggle-like");

um das Klickereignis abzufangen, die Bedingung zu prüfen und dann ein benutzerdefiniertes Modal anzuzeigen.

1 „Gefällt mir“

Ich weiß die Mühe, die du dir hier gemacht hast, um das so klar zu dokumentieren, David, wirklich zu schätzen!

Ich habe es fast geschafft, die Deprecations für 3.2 an einem Nachmittag für unser größtes Plugin zu beheben.

3 „Gefällt mir“

Wie greift man jetzt auf ein vorhandenes Modal in Core zu, um es zu ändern?

In der Vergangenheit habe ich dies verwendet (was nicht mehr funktioniert):
api.modifyClass("controller:poll-ui-builder", {

In diesem speziellen Fall scheint der Klassenname gut deklariert und unverändert zu sein.

2 „Gefällt mir“

Je nachdem, was Sie ändern müssen, denke ich, dass die beste Lösung darin besteht, ein PluginOutlet zu verwenden, um Ihren benutzerdefinierten Code einzufügen, oder einen PluginOutlet Wrapper, um die Kernimplementierung zu ersetzen/bedingt anzuzeigen. (Sie können einen PR erstellen, um ein Outlet hinzuzufügen, wenn es nicht verfügbar ist)

Wenn Sie modifyClass wirklich verwenden möchten, sollte dies immer noch möglich sein. Es ist nur so, dass das Modal jetzt eine Komponente ist und in components/modal verschachtelt ist, sodass Sie darauf wie folgt zugreifen würden:

api.modifyClass("component:modal/poll-ui-builder", {
   pluginId: "your-custom-plugin-id",

   // benutzerdefinierten Code einfügen
});
4 „Gefällt mir“