Sto inserendo un componente Glimmer in topic-above-footer-buttons. Questo componente Glimmer tenta di mostrare alcuni metadati sull’argomento. Li sto serializzando in topic.my_metadata
Quando i metadati vengono aggiornati da un job in background(!), l’argomento viene aggiornato tramite MessageBus.publish(\"/topic/#{topic.id}\", { reload_topic: true, refresh_stream: true })
Ora questo si aggiorna correttamente nel template:
{{this.args.topic.my_metadata.status}}
Tuttavia, quando vi accedo tramite un getter
get statusMessage() {
return this.args.topic.my_metadata.status;
}
allora
{{ this.statusMessage }}
non si aggiorna.
(E lo stesso vale per tutti i getter che ho e che dipendono in qualche modo da this.args.topic.my_metadata. Questo è il vero problema).
Cosa sto facendo di sbagliato?
Ho già provato molte cose, tra cui definire eventi personalizzati, copiare topic.my_metadata in un @tracked metadata e poi usare this.metadata, eccetera.
Penso che sia garantito che un getter venga rivalutato solo se uno dei valori su cui si basa è tracciato (e cambia)
quindi in questo caso penso che {{this.args.topic.my_metadata.status}} sia meglio, anche se a proposito dovresti scriverlo come: {{@topic.my_metadata.status}}
Beh, non è una questione di “meglio” o meno, c’è molta logica in Javascript che valuta i metadati e, ad esempio, decide se un pulsante debba essere mostrato, come
get showButton() {
// fai alcune operazioni intensive su this.args.topic.my_metadata.foo e this.args.topic.my_metadata.bar
}
quindi ho bisogno dei getter e ho bisogno che si rivalutino in qualche modo.
Inoltre, la documentazione di Glimmer afferma che args e i suoi valori vengono tracciati automaticamente.
Se il template è in grado di tracciarli automaticamente, perché non può farlo il getter?
Anche questo funziona, passando i metadati come argomento
Questa è una parte sfortunata del fatto che siamo a metà strada nella conversione dal sistema di reattività ‘classic’ di Ember (get/set/computed) a @tracked / native-getters di ‘octane’.
Quindi, come discusso sopra, il problema con il tuo esempio è che stai accedendo a una proprietà non @tracked da un native getter.
Accedere al percorso completo direttamente da un template funzionerà, anche se, come dici, limita la logica disponibile.
In alternativa, l’uso di .get() consentirà al nuovo sistema di autotracking di Ember di funzionare con le proprietà classiche (cioè non @tracked).
Quindi, in questo caso, sarebbe
get statusMessage() {
return this.args.topic.get("my_metadata.status");
}
Potresti anche risolvere questo con @computed o è un no-no?
@computed('args.topic.my_metadata.status')
get statusMessage() {
// questo potrebbe essere molto più complicato
return this.args.topic.my_metadata.status;
}
Credo che questo avrebbe il vantaggio di memorizzare nella cache il risultato se il calcolo fosse significativo.
(ovviamente banale in questo esempio ma qualcosa a cui @RGJ ha alluso)
@computed fa parte del classico sistema di reattività di Ember. Non è ufficialmente deprecato, ma cerchiamo di evitare di aggiungerlo a nuovo codice.
Se il tuo getter è abbastanza complicato da giustificare la memorizzazione nella cache, puoi usare @cached:
import { cached } from "@glimmer/tracking";
...
@cached
get statusMessage() {
// questo potrebbe essere molto più complicato
return this.args.topic.my_metadata.status;
}