0

我有一个 ListView,里面有一堆 ListItemView,使用 html 文件中的模板。我很快发现 Backbone 期望视图控制所涉及的元素,以便它可以委托事件等。这个答案显示了自定义外部标记中常见事物(如 id)的标准方法。

我只是觉得我的模板中没有外部标签有点奇怪。如果我想分配一个类甚至改变元素的种类,在模板 IMO 中似乎更直观。在大多数情况下,我可以将视图分配给现有元素,但对于集合的项目视图,它必须从头开始创建新视图和元素。

我可以使用 setElement 将字符串分配给 el 并委托事件。但是,当稍后重新呈现控件时(例如在编辑之后),这会中断与 DOM 的连接。我的解决方案是包装 setSelement,使用 jQuery 的 replaceWith 将旧元素切换为新元素:

window.Backbone.View.prototype.replaceElement = (element) ->
  old = @$el
  @setElement element, true
  old.replaceWith @$el

然后我可以在视图中使用它:

render: () ->
  @replaceElement @template @model.toJSON()
  return @

带模板:

<script id="actionTemplate" type="text/x-handlebars-template">
    <li id="{{id}}"><input type="checkbox" />{{name}}</li>
</script>

任何人都可以看到任何陷阱吗?我主要担心的是,它可能比从现有标签中交换 html 慢,更重要的是它还不够惯用吗?当框架真的希望我只保留模板中标签的内容时,也许我很愚蠢地与框架作斗争?

4

1 回答 1

0

您的方法的问题在于您的@el视图仍然是您已用新视图替换的原始视图。所以你的所有事件监听器仍然监听这个旧元素。所以你必须写这样的东西:

window.Backbone.View.prototype.replaceElement = (element) ->
  old = @$el
  @setElement element, true
  old.replaceWith @$el
  @setElement element

除此之外,如果您只是想创建一个项目列表,那么为每个项目创建一个新的视图实例并不是一个好主意。一个视图包含一个ul元素和一个迭代列表的模板就足够了。

<script id="actionTemplate" type="text/x-handlebars-template">
    <ul>
    {{each items}}
        <li id="{{id}}"><input type="checkbox" />{{name}}</li>
    {{/each}}
    </ul>
</script>
于 2012-09-17T06:35:51.893 回答