访问父骨干视图的属性

Ada*_*ers 9 javascript javascript-framework backbone.js

我有一个调用子视图的骨干视图:

  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() {
    } 
  });
Run Code Online (Sandbox Code Playgroud)

这是子视图:

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

我希望能够在子视图中访问父视图的属性,但它不能使用上面的代码.例如,如何在子视图中访问"foo"变量?

mu *_*ort 10

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);
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/ambiguous/DnvR5/

如果您只想拥有一个MapView,那么您可以lr.MapView.prototype.foo随处参考:

initialize: function() {
  _.bindAll(this, "render");
  console.log(lr.MapView.prototype.foo);
}
Run Code Online (Sandbox Code Playgroud)

请注意,无处不在包含在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); 
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是,添加一个访问器方法MapView:

_foo: 'bar',
foo: function() { return this._foo }
Run Code Online (Sandbox Code Playgroud)

并使用该方法EventView:

initialize: function(options) {
    // ...
    console.log(this.parent.foo());
}
Run Code Online (Sandbox Code Playgroud)

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

  • @AdamVickers:访问者的存在向外界发出信号:'foo()`是MapView公共接口的一部分,而缺少mutator表明外人不应该改变它. (2认同)