2012-04-26 122 views
0

我有三個支柱的看法是這樣的:骨幹觀的繼承到孫級

ParentView = Backbone.View.extend({ 
    addUsers : function() 
    { 
     console.log("Parent's Add User"); 
    }, 

    addProject : function() 
    { 
     console.log("Parent's Add Project"); 
    } 
}); 

ChildView = ParentView.extend({ 
    addProject : function() 
    { 
     var self = this; 

     console.log("Child's add Project"); 

     self.constructor.__super__.addProject.apply(self); 
    } 
}); 

GrandChildView = ChildView.extend({ 
    addItem : function() 
    { 
     var self = this; 
     self.addProject(); 
    }, 

    addUsers : function() 
    { 
     var self = this; 
     console.log("Grand Child's Add users"); 
     self.constructor.__super__.addUsers.apply(self); 
    } 
}); 

var vChild = new ChildView(); 
vChild.addProject(); // works fine, by calling it own and parent's functions. 

var vGrandChild = new GrandChildView(); 
vGrandChild.addUsers(); // This throws Maximum call stack size exceeded error, 

當我創建GrandChildView的新實例,然後調用其ADDUSERS方法,它引發的最大堆棧大小超過了,我想這是監守它一直在呼喚自己。但無法弄清楚。 原因似乎是調用super的方法。

謝謝。

+0

我覺得你在用JS中的'super'玩火。 – fguillen 2012-04-26 18:46:21

回答

1

什麼你實際上在做,你應該能夠理解,如果你真的按照你的功能的步驟調用確實是一個無限循環調用的「大孩子」的觀點:)

提示:這是值得演習想什麼this是因爲你每次apply ....;)

否則這可能是你的意思是要達到什麼:

ParentView = Backbone.View.extend({ 
    addUsers : function() 
    { 
     console.log("Parent's Add User"); 
    }, 

    addProject : function() 
    { 
     console.log("Parent's Add Project"); 
    } 
}); 

ChildView = ParentView.extend({ 
    addProject : function() 
    { 
     console.log("Child's add Project"); 

     ParentView.prototype.addProject.call(this); 
    } 
}); 

GrandChildView = ChildView.extend({ 

    addItem : function() 
    { 
     this.addProject(); 
    }, 

    addUsers : function() 
    { 
     console.log("Grand Child's Add users"); 
     ChildView.prototype.addUsers.call(this); 
    } 
}); 

var vChild = new ChildView(); 
vChild.addProject(); // works fine, by calling it own and parent's functions. 

var vGrandChild = new GrandChildView(); 
vGrandChild.addUsers(); 
+0

我同意你的觀點,我有很多意見要像這樣繼承,如果用你建議的方法行事,你能建議嗎?例如,將「ChildView.protoype」指定給擴展它的視圖。就像你在GrandChildView的addUsers中提到的一樣。 – Chetan 2012-04-27 05:57:24

+0

是的使用原型將始終工作。避免超級不惜一切代價。 – ggozad 2012-04-27 08:36:57

0

只是爲了嘗試:添加到您的ChildView:

addUsers : function() 
{ 
    var self = this; 
    console.log("Child's Add users"); 
    self.constructor.__super__.addUsers.apply(self); 
} 

也許作爲addUsers不能正常發揮在ChildView.prototype定義,但它是繼承則沒有發現在self.prototype是中繼。我不知道......就像我說的,我不認爲JS是用這種方式繼承的意思,因爲它是面嚮對象語言的通用

+0

不,這不起作用,因爲它仍然會無限循環。 – Chetan 2012-04-27 05:54:37

0

我把你的代碼,轉換爲CoffeeScript的,它給了我這個JavaScript,它適用於我:

var ChildView, GrandChildView, ParentView, 
    __hasProp = {}.hasOwnProperty, 
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }, 
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; 

ParentView = (function(_super) { 

    __extends(ParentView, _super); 

    ParentView.name = 'ParentView'; 

    function ParentView() { 
    return ParentView.__super__.constructor.apply(this, arguments); 
    } 

    ParentView.prototype.addUsers = function() { 
    return console.log("Parent's Add User"); 
    }; 

    ParentView.prototype.addProject = function() { 
    return console.log("Parent's Add Project"); 
    }; 

    return ParentView; 

})(Backbone.View); 

ChildView = (function(_super) { 

    __extends(ChildView, _super); 

    ChildView.name = 'ChildView'; 

    function ChildView() { 
    this.addProject = __bind(this.addProject, this); 
    return ChildView.__super__.constructor.apply(this, arguments); 
    } 

    ChildView.prototype.addProject = function() { 
    console.log("Child's add Project"); 
    return ChildView.__super__.addProject.apply(this, arguments); 
    }; 

    return ChildView; 

})(ParentView); 

GrandChildView = (function(_super) { 

    __extends(GrandChildView, _super); 

    GrandChildView.name = 'GrandChildView'; 

    function GrandChildView() { 
    this.addUsers = __bind(this.addUsers, this); 

    this.addItem = __bind(this.addItem, this); 
    return GrandChildView.__super__.constructor.apply(this, arguments); 
    } 

    GrandChildView.prototype.addItem = function() { 
    return this.addProject(); 
    }; 

    GrandChildView.prototype.addUsers = function() { 
    console.log("Grand Child's Add users"); 
    return GrandChildView.__super__.addUsers.apply(this, arguments); 
    }; 

    return GrandChildView; 

})(ChildView); 

從我的理解棘手的問題是你是綁定這個自我內部的函數。這種情況在您每次調用具有您調用函數的上下文的函數時都會發生,這正是您想要省略的。你需要在一個函數中綁定這個函數,就像你通常只用於回調函數一樣,或者你沒有引用你正在調用該函數的對象的情況,只是對該函數的引用。所以如果你需要綁定這樣的情況下做這個功能以外。