导入模板的加载在 `this` 中没有对象实例 - 它在哪里?
onload of import template does not have object instance in `this` - where is it?
我尝试使用 html5 导入和 JS 来创建某种 mvc,但现在我遇到了问题。
当我导入一个模板并将其元素附加到我的 DOM 并注册一个事件时,它被触发,一切都很好。
但是 this
实例持有 importet 模板而不是 属性 函数的对象,绑定方法是.... :)
该问题的重要线路 - 了解流程 - 在附近发表评论....
我的问题是:如何将该方法的父对象分配给我的 self
变量?
我有一些控制器父对象:
var controller = function(){
};
controller.prototype.import = function(filepath, callback){
var link = document.createElement('link');
link.rel = 'import';
link.href = filepath;
//important line follows
link.onload = callback;
link.setAttribute("async", '');
document.head.appendChild(link);
return link.import;
};
controller.prototype.display = function(content, selector, target){
var new_element = content.querySelector(selector);
document.querySelector(target).appendChild(new_element.cloneNode(true));
};
还有一些 xyz-controller 扩展控制器(这里是问题所在):
var xyz_controller = function(){
//behold ... here the callback is defined
this.import('/templates/navigation.html', this.init_navigation);
};
xyz_controller.extends(controller);
xyz_controller.prototype.init_navigation = function(){
//if I console.log(this) it holds the imported template and not xyz_controller??
var self = this;
$('#goto-settings').on('click', function(e){
e.preventDefault();
// calls some method I removed for the example, but here was a problem - I sadly cannot call that function
self.settings("param");
return false;
});
};
导航将 dom 元素像这样自行放入父文档(最后在模板文件中):
<script>
xyz.display(document.currentScript.ownerDocument,'#main-navigation', '#Header');
</script>
还有一些 main.JS,它用 jquery 做一些事情,所以:
//to inherit all methods from an object
Function.prototype.extends = function(object){
for(var property in object.prototype){
this.prototype[property] = object.prototype[property];
}
};
var xyz;
$( document ).ready(function(){
xyz = new xyz_controller();
});
在这一行中:
link.onload = callback;
您分配一个函数引用。函数引用通常不会强制调用函数时 this
的内容。这仅在调用函数时确定。
调用函数时,this
的值对应于调用该函数的对象(我过度简化了,参见 this
on MDN)。在这种情况下,调用回调函数的是 DOM(导入文档的),因此该文档确定 this
的值。
即使你像这样更直接地分配它,它仍然不会使用你的对象 this
:
link.onload = this.init_navigation;
为避免这种情况,bind 回调函数显式地 this
;这将否决上述行为:
link.onload = callback.bind(this);
您可能会发现 "How does the “this” keyword work?" 读起来很有趣。
下面是一个片段,说明了 this
关键字的不同行为,具体取决于您是否使用 bind
:
var msg = 'I am a window variable<br>';
var test = {
msg: 'I am a test variable<br>',
whenLoad: function () {
document.body.innerHTML += this.msg;
},
};
window.addEventListener("load", test.whenLoad); // *this* will be window
window.addEventListener("load", test.whenLoad.bind(test)); // *this* will be test
我尝试使用 html5 导入和 JS 来创建某种 mvc,但现在我遇到了问题。
当我导入一个模板并将其元素附加到我的 DOM 并注册一个事件时,它被触发,一切都很好。
但是 this
实例持有 importet 模板而不是 属性 函数的对象,绑定方法是.... :)
该问题的重要线路 - 了解流程 - 在附近发表评论....
我的问题是:如何将该方法的父对象分配给我的 self
变量?
我有一些控制器父对象:
var controller = function(){
};
controller.prototype.import = function(filepath, callback){
var link = document.createElement('link');
link.rel = 'import';
link.href = filepath;
//important line follows
link.onload = callback;
link.setAttribute("async", '');
document.head.appendChild(link);
return link.import;
};
controller.prototype.display = function(content, selector, target){
var new_element = content.querySelector(selector);
document.querySelector(target).appendChild(new_element.cloneNode(true));
};
还有一些 xyz-controller 扩展控制器(这里是问题所在):
var xyz_controller = function(){
//behold ... here the callback is defined
this.import('/templates/navigation.html', this.init_navigation);
};
xyz_controller.extends(controller);
xyz_controller.prototype.init_navigation = function(){
//if I console.log(this) it holds the imported template and not xyz_controller??
var self = this;
$('#goto-settings').on('click', function(e){
e.preventDefault();
// calls some method I removed for the example, but here was a problem - I sadly cannot call that function
self.settings("param");
return false;
});
};
导航将 dom 元素像这样自行放入父文档(最后在模板文件中):
<script>
xyz.display(document.currentScript.ownerDocument,'#main-navigation', '#Header');
</script>
还有一些 main.JS,它用 jquery 做一些事情,所以:
//to inherit all methods from an object
Function.prototype.extends = function(object){
for(var property in object.prototype){
this.prototype[property] = object.prototype[property];
}
};
var xyz;
$( document ).ready(function(){
xyz = new xyz_controller();
});
在这一行中:
link.onload = callback;
您分配一个函数引用。函数引用通常不会强制调用函数时 this
的内容。这仅在调用函数时确定。
调用函数时,this
的值对应于调用该函数的对象(我过度简化了,参见 this
on MDN)。在这种情况下,调用回调函数的是 DOM(导入文档的),因此该文档确定 this
的值。
即使你像这样更直接地分配它,它仍然不会使用你的对象 this
:
link.onload = this.init_navigation;
为避免这种情况,bind 回调函数显式地 this
;这将否决上述行为:
link.onload = callback.bind(this);
您可能会发现 "How does the “this” keyword work?" 读起来很有趣。
下面是一个片段,说明了 this
关键字的不同行为,具体取决于您是否使用 bind
:
var msg = 'I am a window variable<br>';
var test = {
msg: 'I am a test variable<br>',
whenLoad: function () {
document.body.innerHTML += this.msg;
},
};
window.addEventListener("load", test.whenLoad); // *this* will be window
window.addEventListener("load", test.whenLoad.bind(test)); // *this* will be test