Backbone View继承到GrandChild级别

时间:2012-04-26 13:11:03

标签: javascript backbone.js

我有三个这样的主干观点:

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方法时,它会抛出超出的最大堆栈大小,我想这是因为它一直在调用自己。但无法弄清楚。 原因似乎是调用超级方法。

谢谢。

3 个答案:

答案 0 :(得分: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();   

答案 1 :(得分: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不像传统的面向对象语言那样使用继承。

答案 2 :(得分: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);

从我的理解中,棘手的一点是你在函数内部将它绑定到self。每次使用您调用函数的上下文调用函数时都会发生这种情况,这正是您要忽略的内容。您需要在函数中绑定它,因为通常只用于回调,或者您没有引用要调用函数的对象的情况,只是对函数的引用。因此,如果你需要为这种情况绑定它,请在函数外部进行绑定。