由模板控制的主干列表项视图标记

时间:2012-09-17 01:08:41

标签: jquery templates backbone.js idioms

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

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

我可以使用setElement将字符串分配给el并委派事件。但是,当稍后重新渲染控件时(如编辑后),这会破坏与DOM的连接。我的解决方案是使用jQuery的replaceWith来包装setSelement,以使用新元素切换旧元素:

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更慢,更重要的是,它只是不够惯用?也许当我真的希望我只保留模板中标签的内容时,我很难对付框架?

1 个答案:

答案 0 :(得分: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>