Hola a todos,
Puede que esta sea una pregunta un poco básica; soy más bien de back-end. Actualmente estoy intentando conectar algún código de JavaScript con un elemento del front-end. El problema es que mi window.onload (y document.onload, lo intenté con ambos) nunca se dispara. Mi JavaScript está en la carpeta de inicialización del plugin ([plugin]/assets/javascripts/initializers/[plugin].js.es6).
export default {
name: "meritmoot",
initialize() {
//mi función de inicialización
function initializeMeritmoot(api) {
console.log("dentro de initializeMeritmoot")
//función al soltar una tecla
function repInputKeyUp() {
inputBox = document.getElementById("rep-input")
console.log("en 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("Después de la definición de la función");
//carga de la ventana (no ocurre)
window.onload = () => {
console.log("PageLoaded") <-----------------------------------esto nunca se imprime
document.getElementById('rep-input').onkeyup = repInputKeyUp;
};
console.log('saliendo de initializeMeritmoot');
}
console.log("JavaScript de MeritMoot en Default")
withPluginApi("0.8.37", api => initializeMeritmoot(api));
}
};
¿Alguna idea de por qué podría estar ocurriendo esto? ¿Está este JavaScript configurado correctamente en relación con Discourse? ¿O es más bien un problema general de JavaScript?
Edición: intentando con addEventListener…
Edición: sustituyendo onload por:
window.addEventListener('onload', function() {
console.log("PageLoaded")
document.getElementById('rep-input').onkeyup = repInputKeyUp;
}, false);
esto tampoco funcionó.
Estás trabajando con EmberJS aquí, no con JavaScript puro. No se comportará igual.
Lo mejor es seguir las mejores prácticas de EmberJS.
Consideraría integrar tu lógica en un componente existente o agregar uno a un plugin outlet y usar el hook didInsertElement.
Lee las Guías de EmberJS
3 Me gusta
¡Gracias! Vi que Ember era una parte importante de Discourse, pero no me había dado cuenta de que sobrescribía a la versión estándar. Me tomaré el tiempo para aprenderlo.
edición: Estoy usando el elemento del plugin discovery-list-container-top y me conecto a una arquitectura de plugin backend en Ruby.
edición: ¿Cuál es la relación entre ember-rails y Discourse? Ember por sí mismo parece ser un entorno de pila completa. Mirando GitHub - emberjs/ember-rails: Ember for Rails 3.1+ · GitHub
ember-rails es una gema de Ruby que en realidad se utiliza en Discourse.
Los miembros del equipo de Discourse están mejor capacitados para comentar, pero en términos generales, EmberJS se ocupa del front-end y Ruby on Rails del back-end. Por supuesto, Discourse cuenta con elementos de una arquitectura a medida y la configuración exacta es, como en cualquier aplicación grande, al menos en cierta medida única.
Una buena descripción de cómo funcionan las cosas se encuentra aquí Creating Routes in Discourse and Showing Data
La documentación de la API está disponible aquí https://docs.discourse.org
2 Me gusta
He aprendido mucho sobre Ember.js en el último tiempo, pero parece que en la versión incorrecta. Por lo que puedo ver, Discourse utiliza Ember.js 1.9 (según la documentación de ember-rails y la sintaxis del código fuente). La versión actual de Ember.js es la 3.17, por lo que la guía que debería seguir es esta. La sintaxis es bastante diferente, pero ya tengo los conceptos básicos claros. Publicaré el código anterior convertido a Ember.js cuando termine.
2 Me gusta
Ejecutar una instancia de desarrollo en un navegador muestra lo siguiente en la consola de JavaScript:
DEBUG: -------------------------------
DEBUG: Ember : 3.12.2
DEBUG: jQuery : 3.4.1
DEBUG: -------------------------------
Pero tienes razón, algunas de las convenciones de Discourse no reflejan la sintaxis más reciente de las guías 
2 Me gusta
Gracias por la ayuda, Robert. Por un momento me sentí un poco fuera de mi profundidad. De todos modos, aquí está lo que logré al final, como prometí. Terminé usando la función onload, que se activa después de que el DOM se carga. Intenté usar jQuery por un tiempo hasta que escuché que Ember.js estaba deprecándolo.
import { ajax } from 'discourse/lib/ajax';
// Podría actualizar el resaltado para que también funcione con split(" "). Si es que me apetece.
export default Ember.Component.extend({
runOnceRan: false,
myAws: "",
subbedReps: [],
// Actualiza las opciones sugeridas para seguir a representantes en el cuadro de entrada
updatePossibles: function (substr) {
var compContext = this; // contexto del componente
if (substr == "") {
return;
}
// Obtener sugerencias
substr = encodeURIComponent(substr);
ajax(`meritmoot/reps/search/${substr}.json`, { type: "GET" }).then( result => {
result = result.api;
let pv = []; // valores posibles
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;
// Actualizar la lógica interna de Awesomplete
compContext.myAws.evaluate();
// Mostrar sugerencias de Awesomplete
compContext.myAws.open();
});
},
runOnce: function () {
// Confirmar que se ejecutó...
console.log("en runOnce")
const substrInput = document.getElementById("rep-input");
const compContext = this;
// Crear Awesomplete personalizado (lista de opciones) para substrInput (rep-input).
this.myAws = new Awesomplete(substrInput);
console.log(substrInput)
// Todos los elementos de la lista deben mostrarse, ya que se seleccionan con preferencia al cambiar el valor de substr
this.myAws.filter = function (text, input) {
return true
}
// Mostrar siempre, activar autocompletado.
this.myAws.minChars = 0;
this.myAws.autocomplete = "on";
// Al seleccionar una opción, manejarla.
document.addEventListener('awesomplete-selectcomplete', function(e) {
if(e.srcElement == substrInput) {
let id = e.text.value;
substrInput.value = "";
// Enviar selección al backend
let uriid = encodeURIComponent(id)
ajax(`meritmoot/reps/${uriid}`, {type: "PUT" }).then( result => {
console.log("PUT devuelto:");
console.log(result);
});
// Actualizar selección en el frontend
let l = compContext.get("subbedReps");
l.pushObject(id) // se necesita pushObject en lugar de push (https://github.com/emberjs/ember.js/issues/10405)
compContext.set("subbedReps", l);
// 1. HECHO: Crear una tabla que asocie el ID del usuario con los representantes suscritos.
// 2. HECHO: Crear una forma de agregar representantes suscritos a esa tabla. En progreso (necesito GET, PUT, DELETE)
// 3. Mostrar representantes junto a substrInput
// 3. Crear una forma de ver los votos junto a los temas.
// 4. Después de todo eso, actualizar el mecanismo de visualización de votos aquí.
}
}, false);
// Obtener los representantes guardados del usuario y mostrarlos.
ajax(`meritmoot/reps`, {type: "GET"}).then( result => {
console.log("GET devuelto:");
console.log(result);
compContext.set("subbedReps", result.mmfollows);
console.log("subbedReps")
console.log(compContext.get("subbedReps"));
});
// Al escribir, actualizar sugerencias
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);
}
}
});
2 Me gusta