2016-02-24 50 views
1

我玩過HTML5導入和JS創建某種類型的MVC,現在我有一個問題。導入模板的onload在`this`中沒有對象實例 - 它在哪裏?

當我導入模板並將其元素附加到我的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控制器延伸控制器(這裏的問題是):

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元素到父文件由它自己這樣selfe(這是在模板文件中):

而且也有一些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(); 
}); 
+0

是它的工作,如果你使用綁定,當你通過callback?this.import('/ templates/navigation.html',this.init_navigation.bind(this)); –

+0

是的,工作! – helle

回答

3

在這一行:

link.onload = callback; 

您分配一個函數引用。函數引用通常不會強制調用該函數時所要執行的操作。這隻在函數被調用時才被確定。

當函數被調用時,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

相關問題