Javascript onload não está disparando

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 :slight_smile:

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);
    }
  }
});