嘿,各位,
这可能是一个比较基础的问题,我主要是做后端的。目前我正在尝试将一些 JavaScript 代码连接到前端元素。问题是,我的 window.onload(以及 document.onload,我都试过了)从未触发。我的 JavaScript 位于插件初始化文件夹中:[plugin]/assets/javascripts/initializers/[plugin].js.es6
export default {
name: "meritmoot",
initialize() {
// 我的初始化函数
function initializeMeritmoot(api) {
console.log("inside initializeMeritmoot")
// 按键抬起时执行的函数
function repInputKeyUp() {
inputBox = document.getElementById("rep-input")
console.log("in 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("Past Function Def");
// 窗口加载(未发生)
window.onload = () => {
console.log("PageLoaded") <-----------------------------------这行从未打印
document.getElementById('rep-input').onkeyup = repInputKeyUp;
};
console.log('leaving initializeMeritmoot');
}
console.log("MeritMoot Javascript In Default")
withPluginApi("0.8.37", api => initializeMeritmoot(api));
}
};
对于这个问题,大家有什么想法吗?这段 JavaScript 在 Discourse 中的设置是否正确?还是说这是一个通用的 JavaScript 问题?
编辑:尝试使用 addEventListener…
编辑:将 onload 替换为:
window.addEventListener('onload', function() {
console.log("PageLoaded")
document.getElementById('rep-input').onkeyup = repInputKeyUp;
}, false);
但也没有起作用。
您这里使用的是 EmberJS,而非原生 JavaScript。其行为会有所不同。
最好遵循 EmberJS 的最佳实践。
我建议将您的逻辑附加到现有组件上,或将其添加到插件出口中,并使用 didInsertElement 钩子。
请阅读 EmberJS 指南。
3 个赞
谢谢!我注意到 Ember 是 Discourse 的重要组成部分,但没意识到它覆盖了原生功能。我会花时间学习一下。
编辑:我正在使用插件元素 discovery-list-container-top,并连接到 Ruby 后端插件架构。
编辑:ember-rails 和 Discourse 之间有什么关系?Ember 本身似乎是一个全栈环境。查看 GitHub - emberjs/ember-rails: Ember for Rails 3.1+ · GitHub
ember-rails 是一个在 Discourse 中实际使用的 Ruby gem。
Discourse 的工作人员更适合作出评论,但总体而言,EmberJS 负责前端,而 Ruby on Rails 负责后端。当然,Discourse 具有定制架构的元素,其具体配置像任何大型应用一样,至少在某种程度上是独特的。
关于系统运作方式的精彩描述可参见:Creating Routes in Discourse and Showing Data
API 文档位于:https://docs.discourse.org
2 个赞
最近学习了很多 Ember.js 的知识,但看起来是针对错误版本的。据我所知,Discourse 使用的是 Ember.js 1.9(通过查看 ember-rails 文档 和源代码语法可以确认)。Ember.js 的当前版本是 3.17,因此应该参考的指南是 这个。语法差异很大,但我已经掌握了基础知识。完成后,我会将上述代码转换为 Ember.js 版本并发布出来。
2 个赞
在浏览器中运行开发实例时,JavaScript 控制台会显示以下内容:
DEBUG: -------------------------------
DEBUG: Ember : 3.12.2
DEBUG: jQuery : 3.4.1
DEBUG: -------------------------------
但你说得对,Discourse 的一些约定并未完全反映指南中的最新语法:slight_smile:
2 个赞
谢谢你的帮助,Robert!有一段时间我确实有点力不从心!无论如何,正如所承诺的,这是最终成果。我最终使用了 onload 函数,它会在 DOM 加载完成后触发。我曾尝试使用 jQuery,但后来听说 Ember.js 正在弃用它。
import { ajax } from 'discourse/lib/ajax';
// 也可以更新高亮逻辑,使其在 split(" ") 时也生效。当然,如果我有这个想法的话。
export default Ember.Component.extend({
runOnceRan: false,
myAws: "",
subbedReps: [],
// 更新输入框中代表建议选项
updatePossibles: function (substr) {
var compContext = this; // 组件上下文
if (substr == "") {
return;
}
// 获取建议
substr = encodeURIComponent(substr);
ajax(`meritmoot/reps/search/${substr}.json`, { type: "GET" }).then( result => {
result = result.api;
let pv = []; // 可能的值
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;
// 更新 Awesomplete 内部逻辑
compContext.myAws.evaluate();
// 显示 Awesomplete 建议
compContext.myAws.open();
});
},
runOnce: function () {
// 让我们知道它已运行...
console.log("in runOnce")
const substrInput = document.getElementById("rep-input");
const compContext = this;
// 为 substrInput(rep-input)创建自定义 Awesomplete(选项列表)。
this.myAws = new Awesomplete(substrInput);
console.log(substrInput)
// 所有列表项都应显示,因为它们在 substr 值变化时会被有偏见地选中
this.myAws.filter = function (text, input) {
return true
}
// 随时显示,开启自动补全。
this.myAws.minChars = 0;
this.myAws.autocomplete = "on";
// 选项被选中时进行处理。
document.addEventListener('awesomplete-selectcomplete', function(e) {
if(e.srcElement == substrInput) {
let id = e.text.value;
substrInput.value = "";
// 将选择发送到后端
let uriid = encodeURIComponent(id)
ajax(`meritmoot/reps/${uriid}`, {type: "PUT" }).then( result => {
console.log("put passed back:");
console.log(result);
});
// 更新前端选择
let l = compContext.get("subbedReps");
l.pushObject(id) // 需要使用 pushObject 而不是 push(https://github.com/emberjs/ember.js/issues/10405)
compContext.set("subbedReps", l);
// 1. 完成:创建一个将用户 ID 与订阅代表匹配的表格。
// 2. 完成:创建一种向该表格添加订阅代表的方法。进行中(需要 GET、PUT、DELETE)
// 3. 在 substrInput 旁边显示代表
// 3. 创建一种在主题旁边查看投票的方法。
// 4. 完成所有这些后,刷新此处查看投票的机制。
}
}, false);
// 获取用户保存的代表并显示它们。
ajax(`meritmoot/reps`, {type: "GET"}).then( result => {
console.log("get passed back:");
console.log(result);
compContext.set("subbedReps", result.mmfollows);
console.log("subbedReps")
console.log(compContext.get("subbedReps"));
});
// 输入时更新建议
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 个赞