【问题标题】:backbone.js: how to stop event propagation among nested views主干.js:如何停止嵌套视图之间的事件传播
【发布时间】:2014-09-27 14:27:46
【问题描述】:

我正在寻找使视图独立的方法。因此,视图的事件被限制在该视图中,而不是进入子元素或父元素的元素。

backbone.js 框架使用 jQuery .on 方法将事件绑定到视图 (view.el) 的顶部元素。由于我有嵌套视图,当我单击视图 B 的按钮时,事件也会在视图 A 上触发。我知道我可以为视图 B 的按钮单击添加一个处理程序并返回 false,但是这样我需要知道父视图的所有事件并始终处理所有这些事件。

下面是问题的一个例子:http://jsfiddle.net/57RAM/3/

我想点击 MyViewB 按钮并且不触发 ViewA 的事件。 我尝试在视图 B 的事件中添加 'all': -> return false,但没有成功。

有什么建议吗?

【问题讨论】:

  • 事件传播为什么重要?没有捕捉所有事件的好方法 - 您可以检查方法是否以 'on' 开头,例如 stackoverflow.com/questions/5848598/…,仅此而已。如果你这样做,通常会被认为是糟糕的架构,所以我想知道为什么。
  • @DominicTobias 这只是一个例子。我想有孤立的观点,但这似乎并不简单。如果父视图有一个带有“提交”类的按钮,我不想关心它的一个孩子是否已经拥有它。但这似乎很重要,我想创建孤立的视图会变得更加复杂。
  • 正确隔离的只有 Web 组件

标签: jquery backbone.js backbone-views backbone-events jquery-on


【解决方案1】:

您可以在嵌套视图 (MyViewB) 的单击处理程序中使用 ev.stopPropagation() 来防止事件在 DOM 树中冒泡。

【讨论】:

  • 我知道,但这并不能解决我的问题,因为我需要始终处理父视图的所有事件。由于我希望视图可重用且独立于其父视图,因此它不是解决方案。
  • 只检查evt.currentTarget === evt.target是否足够?如果为 false,则表明该事件是否作为传播的一部分被触发,在这种情况下,您可以忽略该事件。
  • 这似乎是一种方法,但我必须在所有事件处理程序中进行此检查,这并不好。
  • 您与 DOM 如何触发和传播事件非常相关。我认为您无法真正按照您描述的方式实现 DOM 事件的解耦。您可以做的实际上是为您关心的事件定义 Backbone 事件并手动管理传播。因此,您无需在父视图上监听点击事件,而是在嵌套视图上监听 Backbone 事件。
【解决方案2】:

如果问题在于视图 B 必须是可重用的,并且如果您不介意视图 A 知道这一点,那么您可以为视图 A 绑定使用更具体的事件选择器。

在示例中,使用了一个简单的“按钮”选择器,它将捕获视图 A 及其子视图 B 中的两个按钮。如果使用了诸如“.btn”或“button.view-a”之类的类将防止问题发生。

下面的sn-p可以看到here使用“.btn”绑定事件。

events:
    'click .btn': 'click'

click: (ev) ->
    alert('MyViewA button click')

initialize: ->
    $('<button class="btn">').text('MyViewA').appendTo(@el)
    child = new MyViewB
    $(child.el).appendTo(@el)

【讨论】:

  • 是的,它会的。我需要始终在类中使用前缀,例如 view-a:button。但是当我有一个 A 类实例作为 A 类实例的子级(或 A 类实例的后代)时,它就行不通了。
  • 显然事件对象可能是一个方法,这样它可能是动态的,因此可以添加一个实例计数器以确保事件仅绑定到在该实例上创建的元素。而且,虽然不是很简单,但它可以解决所描述的继承问题。在实践中:jsfiddle.net/57RAM/5,请注意我在视图 A 构造函数之外创建了子元素以避免无限循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
  • 2011-01-05
  • 1970-01-01
相关资源
最近更新 更多