Wie man feststellt, ob eine Seite in einer Theme-Komponente / einem Widget geladen wird?

Ich habe das Gefühl, mir entgeht hier wahrscheinlich etwas Offensichtliches, aber ich komme nicht weiter. Ich habe eine Theme-Komponente, die einige Widgets lädt, und verwende den folgenden Code, um sie neu zu rendern, nachdem der Benutzer zu einer neuen Seite navigiert ist (übernommen aus den Kategorie-Bannern):

api.decorateWidget("my-widget:after", (helper) => {
    helper.widget.appEvents.on("page:changed", () => {
      helper.widget.scheduleRerender();
    })
});

Dieser Code wartet jedoch, bis die neue Seite vollständig geladen ist, um das Widget zu aktualisieren. Was ich erreichen möchte, ist, den Inhalt meines Widgets sofort auszublenden, sobald jemand auf einen Link zu einer anderen Seite klickt – ähnlich wie bei der nativen Discourse-Funktionalität, bei der Elemente sofort ausgeblendet und beim Klicken ein Ladespinner angezeigt werden.

Ich habe in app\assets\javascripts\discourse\app\templates\discovery.hbs gesehen, dass der div-Container eine Variable “loading” beobachtet, aber ich kann nicht herausfinden, woher diese stammt und wie ich mich daran “ankoppeln” oder den Ladezustand in meinem Widget beobachten kann.

Ich wäre für jede Antwort oder zumindest eine grobe Richtung in die richtige Richtung dankbar. :slight_smile:

Vielen Dank,

Zach

1 „Gefällt mir“

Ich wollte das hier nochmal nach oben holen – ich bin gerne bereit, für Premium-Support zu zahlen, um eine Antwort zu erhalten, falls nötig.

Kannst du kurz beschreiben, welches Verhalten gewünscht ist und auf welchen genau Seiten?

Du kannst stattdessen queueRerender() anstelle von scheduleRerender() verwenden.

Danke für die Antworten, Leute.

Ich habe eine Reihe von Widgets für bestimmte Kategorien erstellt und würde diese idealerweise sofort ausblenden, sobald jemand von einer Seite wegnavigiert. Hier ist eine 45-Sekunden-Loom-Video-Demo dessen, was ich erreichen möchte: Google Chrome - Latest Rental Cities/California topics - Afford Anything Forums - Google Chrome | Loom

@hawm Ich bin mir nicht sicher, dass das erneute Rendern der Warteschlange das Richtige für mich ist, da es hier nicht wirklich darum geht, meine Widgets neu zu rendern, sondern vielmehr darum, meinen Widgets die Möglichkeit zu geben, zu erkennen, ob die globale Discourse-App gerade eine neue Seite lädt.

Je kürzer es ist, desto besser sollte die Bedingung im Template stehen. Zum Beispiel:

{{#if xyz}}
Ihr Code
{{/if}}

Ember-Templates sind dynamisch. Wenn sich der Wert ändert, wird das Widget ausgeblendet.

Ja, natürlich. :slight_smile: Ich habe keine Probleme mit der if/then-Syntax; ich möchte wissen, ob es eine Möglichkeit gibt, zu prüfen, ob Discourse gerade eine neue Seite lädt.

Ich denke, es würde funktionieren, wenn man die modifyClass-API nutzt, um in die discovery-Route einzuhaken und dann ein benutzerdefiniertes Event auslöst.

https://api.emberjs.com/ember/3.12/classes/Route

Die Variable loading stammt aus der discovery-Route, die ich oben erwähnt habe. Das Widget, das an den plugin-outlet angehängt ist, hat möglicherweise keinen Zugriff darauf, da sie nicht als Argument übergeben wird. Das hängt von der Definition des plugin-outlet ab.

Okay, vielen Dank! Ich werde etwas recherchieren, sehen, was ich finde, und falls ich eine Lösung entdecke, diese hier für die Nachwelt aktualisieren :slight_smile:

1 „Gefällt mir“

Ich habe endlich eine Lösung gefunden. Ich habe soooooooooo lange daran gesessen, und meiner Meinung nach sollte dieser Code in den Kern integriert werden, da er eigentlich ohnehin dort vorhanden sein sollte.

Ich habe den untenstehenden Code zu meiner Theme-Komponente hinzugefügt: Er fügt dem <body>-Element sofort eine “loading”-Klasse hinzu, sobald das Routing beginnt, und entfernt sie wieder, sobald das Routing abgeschlossen ist. Vielleicht ist das für Leute, die Ember kennen, einfach oder offensichtlich, aber es hat mir eine unglaublich lange Zeit gekostet (und ich habe eine Million Dinge ausprobiert und alle hier verfügbaren Threads durchgelesen), um darauf zu kommen.

Mit diesem Kern-Code kann ich in meinen verschiedenen Widgets Ladespinner und ähnliches hinzufügen, deren CSS und Sichtbarkeit davon abhängen, ob das <body>-Element die CSS-Klasse loading hat oder nicht.

initialize() {
    withPluginApi("0.8.8", (api) => {
      const router = api._lookupContainer('router:main');
      router.reopen({
        addLoadingCSSClassToBody: function() {
          document.body.classList.add("loading");
        }.on('willTransition')
      });

      router.reopen({
        removeLoadingCSSClassFromBody: function() {
          document.body.classList.remove("loading");
        }.on('didTransition')
      });
    });
  },
};
1 „Gefällt mir“

Der Code, den ich teile, stammt nicht aus einem Widget, sondern aus einer Komponente, die wir zum Download hier auf Meta veröffentlicht haben.

Dort verwenden wir den Router zusammen mit @discourseComputed, um zu prüfen, ob sich die Route geändert hat, und rendern entsprechend.

Wenn du mehr darüber erfahren möchtest, wie es funktioniert, kannst du tiefer in den Code eintauchen.

4 „Gefällt mir“