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