Reputation: 1468
I have three backbone views like this :
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,
when I create new instance of GrandChildView and then call its addUsers method, it throws maximum stack size exceeded, I guess that is becuase it keeps calling itself. but not able to figure out. the reason seems to be calling super's method.
Thank you.
Upvotes: 0
Views: 614
Reputation: 180
I took your code, converted to CoffeeScript and it gave me this JavaScript, which works for me:
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);
From my understanding the tricky point is you are binding this to self inside the functions. This which will happen each time you call the function with the context you are calling the function, which is exactly what you are trying to omit. You need to bind this in a function as you do it usually only for callback, or situations where you have no reference to the object you are calling the function on, just the reference to the function. So if you need to bind this for such situations do it outside the function.
Upvotes: 0
Reputation: 13105
What you are actually doing, which you should be able to understand if you actually follow the steps of your function calls is indeed calling in an infinite loop the "grand child" view :)
Hint: It's worth the exercise to think what this
is every time as you apply
....;)
Otherwise this is probably what you mean to achieve:
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();
Upvotes: 1
Reputation: 38888
Just for try: add this to your ChildView:
addUsers : function()
{
var self = this;
console.log("Child's Add users");
self.constructor.__super__.addUsers.apply(self);
}
Maybe as the addUsers
function is not properly defined in the ChildView.prototype
but it is inherited then it is not found and is relaying in the self.prototype
. I don't know.. as I say I don't think JS is meaning to work with inheritance this way as common OO oriented language.
Upvotes: 0