【问题标题】:Backbone View event not firing after upgrading Backbone from 0.9 to 1.2将 Backbone 从 0.9 升级到 1.2 后,Backbone View 事件未触发
【发布时间】:2015-08-25 17:22:09
【问题描述】:

我已将我的 Web 应用程序从 Backbone 0.9.10 升级到 Backbone 1.2.1,除了一个例外,一切都很好。请看下面的代码:

define( ['underscore', 'backbone', 'text!templates/myResults.html'], function (_, Backbone, Template) {

  var myView = Backbone.View.extend({

    el: '#myResults',

    initialize: function (options) {
        this.targetLoc = options.targetLoc;         
    },

    events: function() {            
        var _events = {};
        _events ['show ' + this.targetLoc + ' a'] = 'tabClicked';           
        return _events;
    },

    tabClicked: function (e) {
        ....stuff....
    }

    template:  _.template(Template),

    render: function() {
        var outputHTML = this.template({model: this.model.toJSON()});
        this.$el.append(outputHTML);
        return this;
    }   

  });

});

return myView;

在我升级 Backbone 之前,我的 tabClicked 事件触发没有问题。现在它不会触发,当我在events 函数中console.log(this.targetLoc); 时,它说this.targetLocundefined

我什至尝试添加:

this.events['show ' + this.targetLoc + ' a'] = 'tabClicked';

initialize 函数无济于事。

此应用程序正在使用:

  • jQuery 1.9.1
  • jQuery UI 1.10.3
  • 下划线 1.8.3
  • 引导 JS 2.3.1
  • 需要 2.1.5
  • 主干 1.2.1(以前的 0.9.10)

很明显,Backbone 的 0.9 到 1.2 发生了一些变化,有什么想法可以解决我的问题吗?

【问题讨论】:

  • 可能是 changelog 中描述的 1.2.0 更改。 视图现在总是在 setElement 中委托它们的事件。您不能再在 initialize 中修改事件哈希或视图的 el 属性。。我猜这也会影响在events 属性中使用函数,并且在调用事件函数时this.targetLoc 是未定义的,因为它是在initialize 之前调用的。您可以使用调试器或console.log 检查是否是这种情况。
  • @ivarni 这应该是一个答案
  • @coding_idiot 它并不能帮助 OP 解决问题,它只是解释了为什么会出现问题。最有可能的解决方案是找到另一种方法将 targetLoc 注入视图或更改架构,因此不需要它,但问题中没有足够的上下文来提出一个好的解决方法。
  • @ivarni myView 视图是一个嵌套视图,根据我拥有的结果数被调用 N 次。 targetLoc 是一个变量,用于确定要为每个 myView 视图显示哪些数据。不幸的是,它需要在那里。

标签: javascript backbone.js backbone-events


【解决方案1】:

根据changelog,在 1.2.0 中,视图委托其事件的方式发生了变化

视图现在总是在 setElement 中委托它们的事件。您不能再在初始化时修改事件哈希或视图的 el 属性。

因此,您不能再依赖在initialize 中设置的属性来动态创建事件哈希。不过,您也可以使用constructor

plunker 上的快速demo 表明这适用于 1.2.2。

var MyView = Backbone.View.extend({
  constructor: function(options) {
    this.eventTarget = options.eventTarget;
    Backbone.View.apply(this, arguments);
  },
  events: function() {
    var _events = {};
    _events['click ' + this.eventTarget] = 'clicked';
    return _events;
  },
  clicked: function(e) {
    console.log(e);
  },
  render: function() {
    this.$el.html('<a class="foo">click</a>');
  }
});

基本上,您应该能够通过将events 所依赖的逻辑移动到constructor 而不是在initialize 中执行此更改来解决此更改。唯一需要注意的是,您必须记住调用 Backbone.View 的原始构造函数。

所以尝试用

替换你的initialize
constructor: function (options) {
    this.targetLoc = options.targetLoc;
    Backbone.View.apply(this, arguments);         
},

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多