1

我使用 html5 导入和 JS 来创建某种 mvc,现在我遇到了问题。

当我导入模板并将其元素附加到我的 DOM 并注册一个事件时,它会被触发并且一切都很好。 但是随后this实例包含导入模板而不是绑定方法是属性函数的对象.... :)

该问题的重要线路 - 了解流程 - 在附近有评论....

我的问题是:如何将该方法的父对象分配给我的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;
    });
};

导航通过它 selfe 将 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();
});
4

1 回答 1

3

在这一行:

link.onload = callback;

您分配一个函数引用。函数引用通常不会强加this调用函数时的内容。这仅在调用函数时确定。

当一个函数被调用时,它的值this对应于你调用该函数的对象(我过于简单化了,参见thisMDN)。在这种情况下,调用回调函数的是(导入文档的)DOM,因此该文档确定this.

即使您像这样更直接地分配它,它仍然不会将您的对象用于this

link.onload = this.init_navigation;

为避免这种情况,请将回调函数显式绑定this; 这将推翻上述行为:

link.onload = callback.bind(this);

您可能会发现“‘this’关键字是如何工作的?” 有趣的阅​​读。

这是一个片段,说明了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

于 2016-03-24T10:30:34.257 回答