无法一致地访问视图中的Backbone View

时间:2013-09-25 15:42:25

标签: javascript backbone.js backbone-views

我正在尝试为Backbone项目创建一个主视图/控制器,而且我很难正确访问视图中的视图。这是代码:

var Controller = Backbone.View.extend({
    initialize: function() {
        this.characterView = new CharacterView({model: character});
        this.encounterView = new EncounterView({collection: encounter});
        this.characterView.$el.on('click', '.attack', this.charAttack);
    },
    charAttack: function() {
        console.log(this.characterView);
    },
    render: function() {
        this.encounterView.render();
        this.characterView.render();
        console.log(this.characterView.model.toJSON());
    }
});

var controller = new Controller();
controller.render();

charAttack中的this.characterView未定义,而在render函数中,它使用正确的对象。我不确定为什么渲染可以访问this.characterView,但charAttack不能。任何帮助理解这一点将不胜感激。

3 个答案:

答案 0 :(得分:1)

_.bindAll添加到初始化函数中:

initialize: function() {
    _.bindAll(this); // assuming Underscore < 1.5.0
    this.characterView = new CharacterView({model: character});
    this.encounterView = new EncounterView({collection: encounter});
    this.characterView.$el.on('click', '.attack', this.charAttack);
},

这可确保视图函数(包括this)内的charAttack始终引用视图。


要验证您是否遇到此问题,请在Chrome中打开控制台,尝试此操作:

charAttack: function() {
    debugger;
    console.log(this.characterView);
},

然后在控制台中键入此内容并查看它是否绑定到window或其他变量。

答案 1 :(得分:0)

除非您已经实例化了对象,否则无法访问this个元素。

var ModController = function(){
    var characterView;
    var encounterView;

    var Controller = Backbone.View.extend({
        initialize: function() {
            characterView = new CharacterView({model: character});
            encounterView = new EncounterView({collection: encounter});
            this.characterView.$el.on('click', '.attack', this.charAttack);
        },
        charAttack: function() {
            console.log(characterView);
        },
        render: function() {
            encounterView.render();
            characterView.render();
            console.log(this.characterView.model.toJSON());
        } 
    });

    return new Controller();

}

var myController = new ModController(); 
myController.render();

所以我认为Revealing Pattern可以解决你的问题。

答案 2 :(得分:0)

有几点值得注意:

  1. 1你正在使用jQuery绑定DOM事件,实际上是骨干 提供了一种更优雅和有用的机制来实现同样的目标 目标。看看backbone's event hash can be found here
  2. 您正在从事件中调用controller.charAttack 处理程序。执行此操作时,属性thiscontroller.charAttack很可能不会指向'控制器' 它会指向'窗口'。
  3. 有很多方法可以解决这个问题。因为您正在响应click事件,所以您可以使用backbone的events属性绑定事件处理程序。删除行this.characterView.$el…并添加此新属性(通常在initialise声明之前:

    events: {
      'click .attack' : 'charAttack'
    },