api.modifyClass funktioniert manchmal(!) nicht

Bearbeiten: Als Fehler eingestuft.
Vollständige Reproduktion unten.

Ich verwende api.modifyClass in einer Theme-Komponente.
Auf den meisten Seiten funktioniert dies einwandfrei, aber in einigen Themen wird die Eigenschaft beim Neuladen der Seite nicht zum Benutzermodell hinzugefügt. Ich kann nicht herausfinden, warum es auf den meisten Themen funktioniert, aber auf einigen nicht, oder was die Themen, auf denen es nicht funktioniert, gemeinsam haben.
Versteht jemand, was ich hier falsch mache?

TL;DR Das Hinzufügen von api.container.lookup für das Modell, unterhalb von modifyClass, umgeht dieses Problem.

1 „Gefällt mir“

Oh mein Gott. Ich glaube, ich weiß es!

Ich glaube, du musst eine pluginId hinzufügen

     <script type="text/discourse-plugin" version="0.1">
    api.modifyClass('model:user', {
      pluginId: 'my-plugin', 
      testProperty: function() {
        return 1;
      } 
    });
    </script>

Sie ist in späteren Versionen erforderlich. Ich habe gestern tatsächlich PRs für ein paar Themes eingereicht, um dies hinzuzufügen. Ich werde vielleicht doch noch ein Plugin-/Theme-Entwickler.

2 „Gefällt mir“

Danke Jay! Das hat tatsächlich einen Unterschied auf meiner Testinstanz gemacht.
Aber leider ist es keine Allzweckwaffe, das Problem ist immer noch da :frowning:

1 „Gefällt mir“

Ja, die pluginId ist meiner Meinung nach dazu da, zu verhindern, dass Änderungen zweimal angewendet werden. Sollte das Fehlen davon erklären, warum sie noch nicht einmal ausgeführt wurde?

1 „Gefällt mir“

Verdammt. Gerade als ich dachte, ich wüsste etwas. :weinende_katze:

Ich dachte, vielleicht, wenn etwas anderes die Klasse modifizieren würde, könnte es eine Race Condition sein, um zu sehen, welche sie modifiziert. Aber JavaScript ist immer noch größtenteils ein Mysterium für mich.

2 „Gefällt mir“

Es ist immer noch ein Problem mit dem Code, daher ist es vernünftig, es anzusprechen.

1 „Gefällt mir“

Ja, das ist mir auch durch den Kopf gegangen. Aber das schlägt immer noch auf einer Testseite fehl, wenn dies die einzige Theme-Komponente ist.

1 „Gefällt mir“

Interessenshalber, wenn Sie dies in eine Theme-Komponente einfügen, z. B. in:\n- /javascripts/discourse/initializers/test-init.js.es6\n\nändert sich das Verhalten/verbessert es sich stattdessen?\n\nIch bin mir nicht sicher, ob diese Dinge semantisch identisch sind…\n\n… theoretisch sollten beide ausgewertet werden, wenn der Browser aktualisiert wird, danach sollte eine Race Condition beim Routenübergang gegenstandslos sein, da die Änderung bereits angewendet worden sein sollte …

1 „Gefällt mir“

Nein, gleiches Verhalten.

Ich habe eine Theme-Komponente mit javascripts/discourse-test/initializers/initialize-discourse-test.js.es6 erstellt:

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: 'discourse-test-initializer',
  initialize(){
    console.log('here1');
    withPluginApi("0.1", api => {
      console.log('here2');

      api.modifyClass('model:user', {
        pluginId: 'test',
        testFunction: function() {
          console.log('here3');
          return 2;
        }
      });

    });
  }
}

Gibt aus

here1
here2

auf jeder Seite.

Bei einigen Themen funktioniert die Eingabe von Discourse.currentUser.testFunction() in der Konsole und liefert here3 und 2 als Ausgabe.

Bei einigen Themen funktioniert es nicht (Uncaught TypeError: Discourse.currentUser.testFunction is not a function)

2 „Gefällt mir“

Ok, ich habe eine Benachrichtigung von einem hilfreichen Beitrag gesehen, der anscheinend inzwischen entfernt wurde.
Der Vorschlag hat nicht funktioniert, aber er enthielt einen Hinweis, der mir bei der Lösung geholfen hat.

Das Hinzufügen des folgenden Snippets unterhalb des nicht funktionierenden Codes hat die Probleme, die ich hatte, durchweg behoben. Ich habe dies auf mehreren unabhängigen Foren getestet, sowohl auf Stable als auch auf Tests-bestanden. Ich denke, dies sollte als Bug neu eingestuft werden …

<script type="text/discourse-plugin" version="0.1">
const userModel = api.container.lookup("model:user");
</script>

@Johani danke für deine Hilfe!

2 „Gefällt mir“

Klassifizierung als Fehler.

Ich habe ein console.log im Plugin-API-Code app/assets/javascripts/discourse/app/lib/plugin-api.js hinzugefügt, damit protokolliert wird, wann immer modifyClass aufgerufen wird.

Ich habe alle externen Plugins entfernt, um sicherzustellen, dass es keine Konflikte gab.

Reproduktion:

  • Erstellen Sie ein leeres Forum auf stable (also ohne Ember CLI). Dies funktioniert auch nicht auf tests-passed (ohne Ember CLI). Ich habe dies nicht mit Ember CLI getestet.

  • Fügen Sie eine Themenkomponente mit Folgendem in Common - Head hinzu:

#1 Funktioniert


    api.modifyClass('model:user', {
      pluginId: 'test-tc',
      testFunction: function() {
        return 1;
      }
    });

  • Laden Sie die Startseite

  • Die Konsole zeigt modifyClass called for model:user _application-08d9058ddd37ba80992f770509f4919ad0738a17f14fb85167b1dc1f32f8b56e.js:23490:16 Object { pluginId: "test-tc", testFunction: testFunction() }

  • Geben Sie Discourse.currentUser.testFunction() in die Konsole ein

  • “1” wird ausgegeben

#2 Schlägt fehl

  • Gehen Sie zu einem Thema, z. B. ‘Welcome to Discourse’, und laden Sie die Seite neu
  • Die Konsole zeigt dieselben “modifyClass called”-Logs an
  • Geben Sie Discourse.currentUser.testFunction() in die Konsole ein
  • Uncaught TypeError: Discourse.currentUser.testFunction is not a function wird ausgegeben

#3 Schlägt fehl mit Warnung

  • Hängen Sie eine einzelne Zeile am Anfang der Themenkomponente an, sodass sie wie folgt aussieht:

    const userModel = api.container.lookup("model:user");

    api.modifyClass('model:user', {
      pluginId: 'test-tc',
      testFunction: function() {
        return 1;
      }
    });

  • Gehen Sie zu einem Thema, z. B. ‘Welcome to Discourse’, und laden Sie die Seite neu
  • Die Konsole zeigt dieselben “modifyClass called”-Logs an
  • Die Konsole zeigt eine Warnung „model:user“ wurde bereits im Container zwischengespeichert. Änderungen werden nicht angewendet.
  • Geben Sie Discourse.currentUser.testFunction() in die Konsole ein
  • Uncaught TypeError: Discourse.currentUser.testFunction is not a function wird ausgegeben

#4 Funktioniert

  • Verschieben Sie die Lookup-Zeile an das Ende der Themenkomponente, sodass sie wie folgt aussieht:

    api.modifyClass('model:user', {
      pluginId: 'test-tc',
      testFunction: function() {
        return 1;
      }
    });

    const userModel = api.container.lookup("model:user");

  • Gehen Sie zu einem Thema, z. B. ‘Welcome to Discourse’, und laden Sie die Seite neu
  • Die Konsole zeigt dieselben “modifyClass called”-Logs an
  • Geben Sie Discourse.currentUser.testFunction() in die Konsole ein
  • “1” wird ausgegeben :partying_face:
4 „Gefällt mir“

Erneute Überprüfung:

Auf Discourse 2.8 und höher schlägt Fall #2 bei Verwendung von Discourse.User.current().testFunction() weiterhin fehl.

1 „Gefällt mir“

Ich habe auch ein Problem mit modifyClass, bin mir nicht sicher, ob es damit zusammenhängt?: Issues overriding getters in a controller (3.0.0)

Ich habe gerade unsere Warnung für diese Art von Situation verbessert:

und auch diese Dokumentation geschrieben, die die Ursache und die Behebung erklärt:

Ich denke, das sollte alle Bedenken in diesem Thema ausräumen. Wenn nicht, teile bitte ein Beispiel für fehlerhaften Code mit, und ich werde es mir ansehen.

11 „Gefällt mir“

Dieses Thema wurde nach 3 Tagen automatisch geschlossen. Neue Antworten sind nicht mehr möglich.