Backbone.js 访问父主干视图的属性

Backbone.js 访问父主干视图的属性,backbone.js,javascript,javascript-framework,Backbone.js,Javascript,Javascript Framework,我有一个主干视图,它调用一个子视图: lr.MapView = Backbone.View.extend({ el: $('#map'), foo: "bar", initialize: function() { var that = this; _.bindAll(this, "render", "addAllEvents", "addOneEvent"); this.collection = new lr.Events();

我有一个主干视图,它调用一个子视图:

  lr.MapView = Backbone.View.extend({
    el: $('#map'),
    foo: "bar",
    initialize: function() {
      var that = this;
      _.bindAll(this, "render", "addAllEvents", "addOneEvent");
      this.collection = new lr.Events();
      this.collection.fetch({
        success:  function(resp) {
          that.render();
          that.addAllEvents();
        }
      });   
    },

    addAllEvents: function() {
      this.collection.each(this.addOneEvent);
    },

    addOneEvent: function(e) {
      var ev = new lr.EventView({ 
        model:  e
      });
    },

    render: function() {
    } 
  });
  lr.EventView = Backbone.View.extend({
    initialize: function() {
      _.bindAll(this, "render");
      console.log(lr.MapView.foo); // will console.log 'undefined' 
    },
    render: function() {
    }
  });
以下是子视图:

  lr.MapView = Backbone.View.extend({
    el: $('#map'),
    foo: "bar",
    initialize: function() {
      var that = this;
      _.bindAll(this, "render", "addAllEvents", "addOneEvent");
      this.collection = new lr.Events();
      this.collection.fetch({
        success:  function(resp) {
          that.render();
          that.addAllEvents();
        }
      });   
    },

    addAllEvents: function() {
      this.collection.each(this.addOneEvent);
    },

    addOneEvent: function(e) {
      var ev = new lr.EventView({ 
        model:  e
      });
    },

    render: function() {
    } 
  });
  lr.EventView = Backbone.View.extend({
    initialize: function() {
      _.bindAll(this, "render");
      console.log(lr.MapView.foo); // will console.log 'undefined' 
    },
    render: function() {
    }
  });

我希望能够在子视图中访问父视图的属性,但它无法使用上述代码。例如,如何访问子视图中的“foo”变量?

只是猜测,但您是否可以在
地图视图中尝试类似的操作:

addOneEvent: function(e) {
    var that = this,
        ev = new lr.EventView({ 
            model:  e,
            parentView = that
        });
}
_foo: 'bar',
foo: function() { return this._foo }
initialize: function(options) {
    // ...
    console.log(this.parent.foo());
}
然后像这样访问它:

lr.EventView = Backbone.View.extend({
    initialize: function() {
      _.bindAll(this, "render");
      console.log(this.parentView.foo);
    },
    render: function() {
    }
  });

lr.MapView
是一个“类”,所有构建的
Backbone.View.extend
都将在
lr.MapView.prototype
中,而不是在
lr.MapView
中。在控制台打开的情况下运行此操作,您将看到发生了什么:

var MapView = Backbone.View.extend({ foo: 'bar' });
console.log(MapView);
console.log(MapView.prototype);
console.log(MapView.prototype.foo);
演示:

如果您只需要一个MapView,那么您可以在任何地方参考
lr.MapView.prototype.foo

initialize: function() {
  _.bindAll(this, "render");
  console.log(lr.MapView.prototype.foo);
}
请注意,everywhere包含在
lr.MapView
实例中,因此您的
foo
将充当来自非原型OO语言的“类变量”

正确的方法是为
foo
使用实例变量,并在创建子视图实例时将父视图实例传递给子视图实例:

// In MapView
addOneEvent: function(e) {
  var ev = new lr.EventView({
    model: e,
    parent: this
  });
}

// In EventView
initialize: function(options) {
  _.bindAll(this, "render");
  this.parent = options.parent; // Or use this.options.parent everywhere.
  console.log(this.parent.foo); 
}
或者更好的方法是,在
MapView
中添加一个访问器方法:

addOneEvent: function(e) {
    var that = this,
        ev = new lr.EventView({ 
            model:  e,
            parentView = that
        });
}
_foo: 'bar',
foo: function() { return this._foo }
initialize: function(options) {
    // ...
    console.log(this.parent.foo());
}
并在
EventView
中使用该方法:

addOneEvent: function(e) {
    var that = this,
        ev = new lr.EventView({ 
            model:  e,
            parentView = that
        });
}
_foo: 'bar',
foo: function() { return this._foo }
initialize: function(options) {
    // ...
    console.log(this.parent.foo());
}

即使在JavaScript中,正确的封装和接口也是一个好主意。

回答得很好,谢谢。为什么访问器方法比您提到的其他方法更可取?@AdamVickers:访问器的存在向外部世界发出信号,
foo()
是MapView公共界面的一部分,缺少变异器表明外部人不应该改变它。