Wie man bei jedem Footer-Ladevorgang (oder Seitenladung?) feuert

Ich versuche, ein JavaScript-Formular in einer Fußzeile zu laden.

Im Header habe ich Folgendes:

<script type="text/discourse-plugin" version="0.8">
  let loadScript = require("discourse/lib/load-script").default;

  api.onPageChange(() => {
    loadScript("//js.hsforms.net/forms/current.js").then(() => {
      console.log("doing the thing");
      hbspt.forms.create({
        portalId: "229276",
        formId: "a86ca9cc",
        submitButtonClass: "button orange-button hubspot-button",
        target: ".subscription-form"
      });
    });
  });
</script>

Und im Footer:

<div class="subscription-form clearfix">
  <h5>Registrieren Sie sich für unseren Blog</h5>
</div>

Beim ersten Laden der Seite funktioniert alles einwandfrei. Bei nachfolgenden Seiten (zumindest bei den meisten) wird das Formular jedoch nicht geladen, und es erscheint folgende Fehlermeldung:

Couldn't find target container .subscription-form for HubSpot Form a86ca9cc. Not rendering form onto the page

Ich vermute, dass die Fußzeile erst nach dem Ausführen des Skripts geladen wird.

Ich muss also irgendwie das Ausführen des Skripts verzögern, bis die Fußzeile geladen ist.

In plugin-api.js heißt es:

//  Listen for a triggered `AppEvent` from Discourse.

api.onAppEvent("inserted-custom-html", () => {
  console.log("a custom footer was rendered");
});

Vielleicht muss ich einfach nur wissen, nach welchem AppEvent ich suchen soll?

1 „Gefällt mir“

Hier gibt es dazu ein wenig mehr Information.

Javascripts targeting the footer doesn't work after page transitions - #4 by Johani

Wenn du dies verwendest

api.onAppEvent("inserted-custom-html", () => {
  // some code
});

muss du angeben, welches benutzerdefinierte HTML du ansprechen möchtest – je danach werden unterschiedliche Ereignisse ausgelöst.

In diesem Fall möchtest du den Footer ansprechen. Kannst du das versuchen und schauen, ob es bei dir funktioniert?

api.onAppEvent("inserted-custom-html:footer", () => {
  // some code
});
1 „Gefällt mir“

Ha! Das hat funktioniert! (Natürlich erst nachdem ich sie überzeugt hatte, dass das, was sie im Footer zu tun versuchten, ohnehin nicht sinnvoll war.) Ich bin total begeistert, das endlich geklärt zu haben, und danke dir für deine Hilfe; ich komme langsam dazu, dass mir diese Dinge Sinn ergeben. (Und ich denke, jetzt werden sie den Footer einfach komplett löschen.)

Aha! Keine Ahnung, warum ich nicht auf die Idee kam, nach „footer

1 „Gefällt mir“

Nicht ganz. Dieses Ereignis wird nur ausgelöst, wenn die custom-html-Ember-Komponente gerendert wird.

Also, wo verwenden wir diese Ember-Komponente und was macht sie?

Wir verwenden dies hauptsächlich in der Haupt-Anwendungsvorlage, um zwei Theme-Felder zu rendern.

Theme-Reiter after_header

Theme-Reiter Footer

Beachte, dass wir sie an anderen Stellen verwenden, aber das ist in diesem Kontext nicht relevant.

Beachte, dass der Footer auch triggerAppEvent="true" hat.

Deshalb kannst du folgendes verwenden:

api.onAppEvent("inserted-custom-html:footer", () => {
  // some code
});

Das Gleiche kannst du beim Reiter after_header nicht tun. Discourse löst dafür kein Ereignis aus. Das wird also nicht funktionieren.

api.onAppEvent("inserted-custom-html:top", () => {
  // some code
});

Warum verwenden wir also diese Ember-Komponente, um einige Theme-Felder zu rendern?

Die einfache Antwort lautet: Sie gibt uns viel mehr Kontrolle darüber, wann sie gerendert wird.

Zwei Beispiele dafür … die Themenliste und die Admin-Seite.

Wir möchten den Footer auf der Themenliste nicht rendern, solange noch Themen über das unbegrenzte Scrollen geladen werden müssen.

Außerdem möchten wir keine Banner oder Markup für die Markenidentität der Seite auf der Admin-Seite rendern, die im Reiter after_header hinzugefügt wurden.

Die Verwendung der custom-html-Ember-Komponente gibt uns also eine genauere Kontrolle über solche Dinge.

Zurück zu deiner Frage: Wenn du etwas ausführen musst, wenn der Footer gerendert wird, ist dies der Wrapper, den du brauchst:

api.onAppEvent("inserted-custom-html:footer", () => {
  // some code
});

Diese API-Methode funktioniert für alle App-Ereignisse. Obwohl das Beispiel dort also nicht wirklich vollständig ist, ist es nur ein Beispiel. Es gibt viele andere AppEvents, die du in dieser Methode verwenden kannst. Du kannst hier nachsehen:

Code search results · GitHub

um die Namen einiger ausgelöster Ereignisse zu sehen.

this.appEvents.trigger("EVENT_NAME")

und wie wir uns damit verbinden, um andere Änderungen vorzunehmen:

this.appEvents.on("EVENT_NAME")

Du kannst dich mit jedem Ereignis verbinden, das Discourse Core in deinem Theme auslöst. Wenn ich also Code ausführen möchte, kurz bevor der Composer öffnet:

discourse/app/assets/javascripts/discourse/app/components/composer-editor.js at 1c38b4abf1fab8d67aaaa4b9f2810add64b709c4 · discourse/discourse · GitHub.

kann ich meinem Theme so etwas hinzufügen:

api.onAppEvent("composer:will-open", () => {
  console.log("this fires right before the composer opens");
});

Trotzdem stimme ich dir zu. Wir sollten ein anderes Beispiel für diese Methode in der API-Datei verwenden. Ich habe mir eine Notiz gemacht, um dieses Beispiel zu verbessern.

2 „Gefällt mir“

Das ist eine großartige Antwort und so klar formuliert, dass sogar ich sie verstehen konnte.

Das Problem „Wie löse ich etwas aus?

1 „Gefällt mir“

Hey @Johani, ein weiteres Szenario zu diesem Problem „Wie löse ich etwas aus oder werde ausgelöst

Das hat mir gerade wieder geholfen! Was ich tun musste, war, ein Skript zu laden, wenn der Post-Stream aktualisiert wurde. Alle Beispiele, die ich gefunden habe, waren in Komponenten, die über this Zugriff auf appEvent hatten. Ich habe dies endlich gefunden und kann nun in einem apiInitializer

  api.onAppEvent('post-stream:refresh', args => {
   // do some stuff!!!
  });

Und jetzt werden diese Anzeigen geladen, wenn jede Charge von Beiträgen geladen wird. Ich habe deinen Beitrag bereits mit :heart: markiert, daher musste ich mich ausführlicher bedanken. :wink:

2 „Gefällt mir“

Dies ist eines meiner Lieblingsthemen :heart: Ich komme immer wieder gerne hierher :sweat_smile: Ich schätze das wirklich! :hugs:

1 „Gefällt mir“