1

Backbone 中事件传播的奇怪问题。大多数人问如何停止事件传播,但我正在努力让我的事件传播!

这里我有两个 View 对象。MainView 包含 Item 视图并侦听单击事件以调用 run():

var MainView = Backbone.View.extend({
    ...

    events: {
        "click .item": "run" // works only if no click event in Item
    },

    render: {
         // Item View object children
    },

    run: function() {
        //run :)
    }
});

项目视图对象也会监听自己的点击事件来切换开/关行为:

var Item = Backbone.View.extend({
    ...

    events: {
        "click" : "toggle" // MainView click event works when this is removed
    },

    toggle: function() {
        this.model.toggle();
    }
});

问题是当单击 Item 时 MainView.run() 没有被触发,而 Item.toggle() 有一个 click 事件。

但是,如果我删除 Item.toggle() 单击事件,MainView.run()触发。让我得出这样的结论,即事件以某种方式被迫停止传播,超出了我的控制。

我怎么解决这个问题?我是否遗漏了一些明显的东西,或者这是不可避免的?

感谢您的任何和所有建议和答案:)。

4

2 回答 2

0

Jay B. Martin 回答了这个问题。

问题是视图调用 this.model.toggle();

toggle() 函数设置 MainView 正在侦听的一些变量,从而触发 render() 事件。

当 MainView 调用 render() 时,Item 视图依次被移除、渲染并添加到 DOM。这会使用事件:{} 丢失与 DOM 元素的绑定事件。

相反,应该使用 _.bind() 或 _.bindAll() 来永久绑定事件,无论绑定到 DOM 中的元素的上下文/状态如何。


原评论答案:

@Dan0,对不起,我对切换如何成为您问题的根源感到有些困惑。我认为这是通过绑定到嵌套视图中的隐式 DOM 元素而产生的上下文歧义的症状。一旦调用了toggle,click 事件就会丢失它最初绑定的上下文(即this.el)。解决这个问题的惯用方法是 a) 传递一个显式元素,以便它可以在后续事件上重新绑定,或者 b) 使用 _.bind 或 _.bindAll,以便单击事件永久绑定到 itemview 作为上下文变化。– Jay B. Martin 8 月 10 日 23:46

于 2013-08-17T14:54:32.447 回答
0

您的项目视图中的单击事件似乎未绑定到特定的 DOM 对象。侦听通用点击事件可能会覆盖 Backbone 侦听您的特定 .item 点击事件。尝试将 ID 或类名添加到您的项目视图单击事件以消除任何歧义。

var Item = Backbone.View.extend({

  ...

  events: {
    "click .some-class" : "toggle" // This should fix your problem
  },

  ...   
于 2013-08-09T15:55:36.997 回答