Ei pessoal,
Isso pode ser uma pergunta um pouco básica, sou mais da área de back-end. Atualmente, estou tentando conectar algum código JavaScript a um elemento do front-end. O problema é que meu window.onload (e document.onload, tentei os dois) nunca é acionado. Meu JavaScript está na pasta de inicialização do plugin ( [plugin]/assets/javascripts/initializers/[plugin].js.es6 )
export default {
name: "meritmoot",
initialize() {
// minha função de inicialização
function initializeMeritmoot(api) {
console.log("dentro de initializeMeritmoot")
// função ao soltar uma tecla
function repInputKeyUp() {
inputBox = document.getElementById("rep-input")
console.log("em rep input key up")
ajax("/reps/search/" + inputBox.value +".json", {type: 'GET'}).then((result) => {
console.log(result)
result = JSON.parse(result)
repList = document.getElementById("rep-list")
repList.innerHTML = ""
result.forEach(op => {
var x = document.createElement("INPUT");
x.setAttribute("info-tag-id", op.id)
x.setAttribute("value", op.mm_reference_str)
repList.appendChild(x)
});
console.log(repList)
});
};
console.log("Após definição da função");
// carregamento da janela (não acontece)
window.onload = () => {
console.log("PageLoaded") <-----------------------------------isso nunca é impresso
document.getElementById('rep-input').onkeyup = repInputKeyUp;
};
console.log('saindo de initializeMeritmoot');
}
console.log("JavaScript do MeritMoot no Default")
withPluginApi("0.8.37", api => initializeMeritmoot(api));
}
};
Alguma ideia do porquê isso pode estar acontecendo? Esse JavaScript está configurado corretamente em relação ao Discourse? Ou é mais algo geral de JavaScript?
Edição: tentando adicionar addEventListener…
Edição: substituindo onload por:
window.addEventListener('onload', function() {
console.log("PageLoaded")
document.getElementById('rep-input').onkeyup = repInputKeyUp;
}, false);
isso também não funcionou
Você está trabalhando com EmberJS aqui, não com JavaScript puro. O comportamento não será o mesmo.
O ideal é seguir as melhores práticas do EmberJS.
Eu consideraria integrar sua lógica a um componente existente ou adicionar um a uma plugin outlet e usar o hook didInsertElement.
Leia os Guias do EmberJS
Obrigado! Vi que o Ember era uma parte importante do Discourse, mas não percebi que ele substituía o vanilla. Vou dedicar um tempo para aprendê-lo.
edit: Estou usando o elemento de plugin discovery-list-container-top e conectando-o a uma arquitetura de plugin backend em Ruby.
edit: Qual é a relação entre o ember-rails e o Discourse? O Ember por si só parece ser um ambiente full stack. Analisando GitHub - emberjs/ember-rails: Ember for Rails 3.1+ · GitHub
ember-rails é uma gem Ruby que é efetivamente utilizada no Discourse.
Os colaboradores do Discourse estão mais aptos a comentar, mas de forma geral, o EmberJS lida com o front-end e o Ruby on Rails com o back-end. É claro que o Discourse possui elementos de uma arquitetura personalizada e a configuração exata é, como em qualquer grande aplicação, pelo menos parcialmente única.
Uma boa descrição de como as coisas funcionam está aqui: Creating Routes in Discourse and Showing Data
A documentação da API está aqui: https://docs.discourse.org
Aprendi bastante sobre Ember.js recentemente, mas parece que foi na versão errada. Pelo que pude verificar, o Discourse usa o Ember.js 1.9 (consultando a documentação do ember-rails e a sintaxe do código-fonte). A versão atual do Ember.js é a 3.17. Portanto, o guia que deve ser seguido é este aqui. A sintaxe é bastante diferente, mas já dominei o básico. Assim que terminar, postarei o código acima convertido para Ember.js.
Executar uma instância de desenvolvimento no navegador revela o seguinte no console do JavaScript:
DEBUG: -------------------------------
DEBUG: Ember : 3.12.2
DEBUG: jQuery : 3.4.1
DEBUG: -------------------------------
Mas você está certo, algumas das convenções do Discourse não refletem a sintaxe mais recente dos guias 
Obrigado pela ajuda, Robert! Fiquei um pouco perdido com isso por um tempo! De qualquer forma, aqui está o que consegui no final, como prometido. Acabei usando a função onload, que é acionada após o carregamento do DOM. Tentei usar jQuery por um tempo, até ouvir que o Ember.js estava depreciando seu uso.
import { ajax } from 'discourse/lib/ajax';
// Poderia atualizar o destaque para também funcionar com o split(" "). Se, você sabe, eu sentir vontade.
export default Ember.Component.extend({
runOnceRan: false,
myAws: "",
subbedReps: [],
// Atualiza as opções sugeridas para seguir representantes na caixa de entrada
updatePossibles: function (substr) {
var compContext = this; // contexto do componente
if (substr == "") {
return;
}
// obter sugestões
substr = encodeURIComponent(substr);
ajax(`meritmoot/reps/search/${substr}.json`, { type: "GET" }).then( result => {
result = result.api;
let pv = []; // valores possíveis
for(let i = 0; i < result.length; i++) {
let newItem = {
label: result[i].mm_reference_str,
value: result[i].id,
id: result[i].id,
}
pv.push(newItem);
}
console.log(pv)
compContext.myAws.list = pv;
// atualiza a lógica interna do Awesomplete
compContext.myAws.evaluate();
// mostra as sugestões do Awesomplete
compContext.myAws.open();
});
},
runOnce: function () {
// nos avisa que foi executado...
console.log("em runOnce")
const substrInput = document.getElementById("rep-input");
const compContext = this;
// cria um Awesomplete personalizado (lista de opções) para substrInput (rep-input).
this.myAws = new Awesomplete(substrInput);
console.log(substrInput)
// todos os itens da lista devem ser mostrados, pois são selecionados com preconceito na mudança do valor de substr
this.myAws.filter = function (text, input) {
return true
}
// mostra sempre, ativa o autocomplete.
this.myAws.minChars = 0;
this.myAws.autocomplete = "on";
// ao selecionar uma opção, trata-a.
document.addEventListener('awesomplete-selectcomplete', function(e) {
if(e.srcElement == substrInput) {
let id = e.text.value;
substrInput.value = "";
// envia a seleção para o backend
let uriid = encodeURIComponent(id)
ajax(`meritmoot/reps/${uriid}`, {type: "PUT" }).then( result => {
console.log("put retornou:");
console.log(result);
});
// atualiza a seleção no frontend
let l = compContext.get("subbedReps");
l.pushObject(id) // pushObject é necessário em vez de push (https://github.com/emberjs/ember.js/issues/10405)
compContext.set("subbedReps", l);
// 1. FEITO: criar uma tabela que mapeia o ID do usuário para os representantes assinados.
// 2. FEITO: criar uma maneira de adicionar representantes assinados a essa tabela. em andamento (precisa de GET, PUT, DELETE)
// 3. visualizar representantes ao lado de substrInput
// 3. criar uma maneira de visualizar votos ao lado dos tópicos.
// 4. após tudo isso, atualizar esse mecanismo de visualização de votos aqui.
}
}, false);
// obtém os representantes salvos do usuário e os mostra.
ajax(`meritmoot/reps`, {type: "GET"}).then( result => {
console.log("get retornou:");
console.log(result);
compContext.set("subbedReps", result.mmfollows);
console.log("subbedReps")
console.log(compContext.get("subbedReps"));
});
// ao digitar, atualiza as sugestões
document.addEventListener('input', function(e) {
if(e.explicitOriginalTarget == substrInput) {
compContext.updatePossibles(substrInput.value);
}
}, false)
console.log(this.myAws);
},
didRender() {
this._super(...arguments);
if( ! this.runOnceRan ) {
this.runOnce();
this.set("runOnceRan", true);
}
}
});