【问题标题】:Backbone events not firing after refreshing the events via fetch通过 fetch 刷新事件后未触发主干事件
【发布时间】:2012-05-22 14:09:42
【问题描述】:

我正在使用backbone.marionette 并有以下CollectionView ItemView 组合:

  PlansListItemView = PlansApp.ItemView.extend
    tagName: "tbody"
    template: "#plansRow"    
    events:
      'click th.expander': 'expandDocuments'

    expandDocuments: (e) =>
      # do stuff

  PlansCollectionView = PlansApp.CollectionView.extend
    tagName: "table"
    itemView: PlansListItemView 

我从嵌入在页面上的初始 json 集合创建视图。事件哈希中的事件完美运行。

然后在下拉更改事件中,我在集合上调用 fetch() 以检索新的对象集合。 DOM 被重建,但事件处理程序没有被重新附加/

有人知道为什么会发生这种情况吗?

【问题讨论】:

  • 在重建 DOM 后你的 th 有没有“expander”类?
  • @Brendan 是的,类是在模板中指定的。
  • 您可以发布您的项目视图模板吗? #plansRow?
  • 好的...我在想它不起作用的唯一原因是因为 jquery 找不到选择器。所以另一个问题......当你第一次渲染时,你在控制台上看到任何错误吗?我问的原因是因为我们最近遇到了点击不起作用的情况,结果发现有错误。它并没有阻碍渲染,但事情就是行不通。
  • 我突然想到,一旦你重新渲染,你可以调用delegateEvents来更新DOM事件钩子。试试看,看看会发生什么。

标签: backbone.js marionette


【解决方案1】:

虽然我不知道确切的原因,但你的设置中有一些有趣的东西让我认为这可能是问题的一部分。

注意:根据您发布的内容,我对您的代码和模板做出了一些巨大的假设。任何数量的事情都可能发生,这会使我所说的大部分内容无效。不过,鉴于您发布的内容,以下是我对如何组织此代码的想法,这可能有助于清理您看到的问题。

HTML 输出错误?

您将每个项目视图设置为 <tbody> 标记,但看起来您有一些由该视图呈现的 <th> 标记 - 至少基于您配置的事件。

这将产生无效的HTML,例如:

<table>
  <tbody>
    <th></th>
  </tbody>
</table>

如果没有看到#plansRow 的模板,很难说,但我猜想这会产生类似的结果。

问题在于集合视图不擅长生成表格。他们可以很好地在表格中生成行,以及表格标签包装器,但他们将无法获得良好的表格结构所需的表格标题、页脚、正文或其他标签,因为集合视图不呈现模板他们自己的。他们只是创建一个包装标签,然后渲染集合中的每个子元素。

要纠正这个问题,请使用 CompositeView,它是一个 CollectionView,它也呈现自己的模板。

具有复合视图的更好的表结构

使用 Marionette 构建表格的更合适的设置是使用 CompositeView 作为父项,并让每个项目视图呈现一个 tr 标记。例如:


RowView = Backbone.Marionette.ItemView.extend({
  template: "#row-template",
  tagName: "tr"
});

TableView = Backbone.Marionette.CompositeView.extend({
  template: "#table-template",
  tagName: "table",

  appendHtml: function(cv, iv){
    cv.$("tbody").append(iv.el);
  }
});

这将使用复合视图设置&lt;table&gt;。然后,该视图的模板将包含适当的&lt;thead&gt;&lt;th&gt;...&lt;/th&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;/tbody&gt; 标记来定义表。

行视图呈现为&lt;tr&gt; 标记,并填充它需要的任何数据,包括适当的&lt;td&gt; 标记。

复合视图上的appendHtml 方法处理将每个项目视图插入到父复合视图的&lt;tbody&gt; 标记中。

你可以在这个 JSFiddle 中看到它的实时版本:http://jsfiddle.net/derickbailey/me4NK/

还有一篇介绍 CompositeView 的这种用途和其他用途的博文,请点击此处:http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/

【讨论】:

  • 感谢您的详细回答。我会告诉你进展如何。
  • 完全正确!重构为复合视图解决了这个问题,而无需调用 delegateEvents,这是我的下一个选择。我现在可以看到何时使用复合视图,但我何时使用 CollectionView 或曾经使用过?
  • 很高兴它成功了! :) 当您有一个不需要外包装的集合时,使用集合视图。一个简单的&lt;ul&gt; 就是一个很好的例子,因为集合视图可以将它的 tagName 设置为“ul”,然后它可以将每个 itemView 呈现为一个“li”......老实说 - 我不经常使用集合视图。不过,它们是牵线木偶的必要组成部分,因为它们为复合视图提供了基础,并且在某些场景中很有用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多