骨干视图继承到孙子级别



我有三个这样的骨干视图:

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的方法。

谢谢。

你实际在做什么,如果你真的按照函数调用的步骤去做,你应该能够理解,这确实是在无限循环中调用"孙子"视图:)

提示:每次apply时都值得思考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()
    {
        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();   

只是为了尝试:将此添加到您的ChildView:

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

也许由于addUsers函数在ChildView.prototype中没有正确定义,但它被继承了,然后找不到它并在self.prototype中中继。我不知道。。正如我所说,我不认为JS的意思是以这种方式将继承作为通用的面向对象的语言

我拿了你的代码,转换成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);

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

最新更新