Ich füge eine Glimmer-Komponente in topic-above-footer-buttons ein. Diese Glimmer-Komponente versucht, einige Metadaten über das Thema anzuzeigen. Ich serialisiere diese in topic.my_metadata.
Wenn die Metadaten aus einem Hintergrundjob aktualisiert werden(!), wird das Thema über MessageBus.publish(\"/topic/#{topic.id}\", { reload_topic: true, refresh_stream: true }) aktualisiert.
Dies wird nun korrekt in der Vorlage aktualisiert:
{{this.args.topic.my_metadata.status}}
Wenn ich jedoch über einen Getter darauf zugreife:
get statusMessage() {
return this.args.topic.my_metadata.status;
}
dann wird {{ this.statusMessage }} nicht aktualisiert.
(Und dasselbe gilt für alle Getter, die auf irgendeine Weise von this.args.topic.my_metadata abhängen. Das ist das eigentliche Problem).
Was mache ich falsch?
Ich habe bereits vieles versucht, darunter die Definition benutzerdefinierter Ereignisse, das Kopieren von topic.my_metadata in ein @tracked metadata und dann die Verwendung von this.metadata usw.
Ich glaube, Sie haben nur dann eine Garantie, dass ein Getter neu ausgewertet wird, wenn einer der Werte, auf die er angewiesen ist, verfolgt wird (und sich ändert).
In diesem Fall ist {{this.args.topic.my_metadata.status}} meiner Meinung nach besser, obwohl Sie es übrigens so schreiben sollten: {{@topic.my_metadata.status}}.
Nun, es ist keine Frage von “besser” oder nicht, es gibt viel Logik in Javascript, die die Metadaten auswertet und zum Beispiel entscheidet, ob ein Button angezeigt werden soll, wie zum Beispiel
get showButton() {
// tue einige rechenintensive Dinge mit this.args.topic.my_metadata.foo und this.args.topic.my_metadata.bar
}
daher brauche ich die Getter und ich brauche sie, um sich irgendwie neu zu bewerten.
Zusätzlich besagt die Glimmer-Dokumentation, dass args und seine Werte automatisch verfolgt werden.
Wenn die Vorlage sie automatisch verfolgen kann, warum kann der Getter das nicht?
Selbst das funktioniert, indem die Metadaten als Argument übergeben werden
Dies ist ein unglücklicher Teil unserer Umstellung von Embers ‘classic’ Reaktivitätssystem (get/set/computed) auf das ‘octane’ @tracked / native-getters.
Wie oben besprochen, besteht das Problem mit Ihrem Beispiel darin, dass Sie von einem nativen Getter auf eine Nicht-@tracked-Eigenschaft zugreifen.
Der direkte Zugriff auf den vollständigen Pfad von einer Vorlage aus funktioniert, schränkt jedoch, wie Sie sagen, die verfügbare Logik ein.
Alternativ ermöglicht die Verwendung von .get() Embers neuem Autotracking-System, mit klassischen (d. h. nicht @tracked) Eigenschaften zu arbeiten.
In diesem Fall wäre es also
get statusMessage() {
return this.args.topic.get("my_metadata.status");
}
@computed ist Teil von Embers klassischem Reaktionssystem. Es ist nicht offiziell veraltet, aber wir versuchen, es in neuem Code zu vermeiden.
Wenn Ihr Getter kompliziert genug ist, um eine Zwischenspeicherung zu rechtfertigen, können Sie @cached verwenden:
import { cached } from "@glimmer/tracking";
...
@cached
get statusMessage() {
// dies könnte viel komplizierter sein
return this.args.topic.my_metadata.status;
}