Olá pessoal. Estou tentando desvendar um problema com o que eu acho que é o ciclo de vida do objeto DOM. Li todo este tópico A tour of how the Widget (Virtual DOM) code in Discourse works, mas ele ainda não me ajuda a responder minha pergunta, ou pelo menos me aponta uma direção para tentar resolver meu problema. Estou tendo dificuldade em entender.
Escrevi um plugin muito básico como um wrapper para um serviço externo (o motor de chat Rumbletalk, para ser exato). O plugin funciona como eu gostaria, o chat funciona, etc., exceto se você navegar para longe do chat para alguma outra parte do meu site e depois voltar para o chat. Recebo um erro do JavaScript incluído deles que estou tentando criar um chat duplicado.
O plugin é um simples hbs/widget que cria o seguinte HTML
Presumo que em algum lugar no DOM, o HTML renderizado ainda esteja por perto, e quando esta tag de script carrega e executa novamente, ela a detecta. Quando depuro no console de desenvolvimento, estou vendo o erro sendo lançado do JavaScript da tag de script, não do código de login.
Entrei em contato com a equipe do Rumbletalk, mas ainda não obtive resposta. Alguém tem alguma sugestão sobre o que posso olhar em seguida? A única coisa que consegui fazer foi adicionar um manipulador window.onerror e depois fazer um location.reload(). Obviamente, esta não é uma boa solução. Existe alguma maneira de eu ‘limpar’ os objetos DOM do motor de chat quando a página perde o foco?
Este script executa um IIFE, inicializa uma instância e armazena a instância no escopo global. O escopo global é o mesmo para toda a sessão no Discourse porque é uma aplicação de página única. Você pode verificar isso com
console.log(RumbleTalkChat)
Após o script carregar pela primeira vez. Portanto, RumbleTalkChat["$MY_OTHER_ID"] é o que o script está reclamando
if (e.RumbleTalkChat[a.hash]) {
throw new Error("Trying to create a duplicate chat with code: " + a.hash);
}
Você pode tentar remover essa instância antes que o script carregue novamente com algo como isto
delete RumbleTalkChat["$MY_OTHER_ID"]
Note que ele não contém o caractere ?.
Dito isso, você provavelmente ficará melhor se descobrir por que o script está sendo carregado várias vezes em primeiro lugar. Vejo que o script tem um método openChat() que você pode chamar. Portanto, carregar o script várias vezes pode não ser necessário.
Infelizmente, você precisaria fornecer mais detalhes sobre onde o embed vai e como você está adicionando a marcação antes que possamos identificar a causa.
Olá Joe
Obrigado pela explicação do IIFE, eu presumi que era ALGO assim, ou, como o título dizia, era um objeto com escopo DOM. Eu vi a verificação
if (e.RumbleTalkChat[a.hash]) {
throw new Error("Trying to create a duplicate chat with code: " + a.hash);
}
no módulo também. Esse módulo é carregado com o resto da página na renderização do widget. Vou ver se consigo mover isso possivelmente para o inicializador e, em seguida, apenas renderizar o formulário.