Estou inserindo um componente Glimmer em topic-above-footer-buttons. Este componente Glimmer tenta mostrar alguns metadados sobre o tópico. Estou serializando-os para topic.my_metadata
Quando os metadados são atualizados de um job em segundo plano(!), o tópico é atualizado via MessageBus.publish(\"/topic/#{topic.id}\", { reload_topic: true, refresh_stream: true })
Agora isso atualiza corretamente no template:
{{this.args.topic.my_metadata.status}}
No entanto, quando o acesso através de um getter
get statusMessage() {
return this.args.topic.my_metadata.status;
}
então
{{ this.statusMessage }}
não atualiza.
(E o mesmo vale para todos os getters que tenho e que dependem de this.args.topic.my_metadata de alguma forma. Que é o problema real).
O que estou fazendo de errado?
Já tentei muita coisa, incluindo definir eventos personalizados, copiar topic.my_metadata para um @tracked metadata e então usar this.metadata, etcetera.
Acho que você só tem a garantia de que um getter será reavaliado se um dos valores em que ele se baseia for rastreado (e isso mudar)
então, neste caso, acho que {{this.args.topic.my_metadata.status}} é melhor, embora, a propósito, você deva escrever assim: {{@topic.my_metadata.status}}
Bem, não se trata de ser “melhor” ou não, há muita lógica em Javascript avaliando os metadados e, por exemplo, decidindo se um botão deve ser exibido, como
get showButton() {
// faz algumas coisas pesadas com this.args.topic.my_metadata.foo e this.args.topic.my_metadata.bar
}
então eu preciso dos getters e preciso que eles reavaliem de alguma forma.
Além disso, a documentação do Glimmer diz que args e seus valores são rastreados automaticamente.
Se o template é capaz de rastreá-los automaticamente, por que o getter não pode?
Até mesmo isso funciona, passando os metadados como um argumento
Esta é uma parte infeliz de estarmos no meio da conversão do sistema de reatividade ‘clássico’ do Ember (get/set/computed) para @tracked / getters nativos do ‘octane’.
Portanto, como discutido acima, o problema com seu exemplo é que você está acessando uma propriedade não @tracked de um getter nativo.
Acessar o caminho completo diretamente de um template funcionará, embora, como você diz, isso limite a lógica disponível.
Alternativamente, usar .get() permitirá que o novo sistema de autotracking do Ember funcione contra propriedades clássicas (ou seja, não @tracked).
Portanto, neste caso, seria
get statusMessage() {
return this.args.topic.get("my_metadata.status");
}
@computed faz parte do sistema de reatividade clássico do Ember. Ele não é oficialmente descontinuado, mas tentamos evitar adicioná-lo a novos códigos.
Se o seu getter for complicado o suficiente para justificar o cache, você pode usar @cached:
import { cached } from "@glimmer/tracking";
...
@cached
get statusMessage() {
// isso pode ser muito mais complicado
return this.args.topic.my_metadata.status;
}