[英]Reassign Backbone View to newly created DOM element
我正在使用Backbone与CoffeeScript和Handlebars一起创建搜索结果页面。 我有两个视图:一个用于结果列表(ListView),第二个视图用于单个结果(ResultView)。 简化代码:
ListView = Backbone.View.extend
el: $("ul#results")
...
addItem: (result) ->
resultView = new ResultView({
model: result
})
resultView.parentView = this
this.el.append(resultView.render().el)
ResultView = Backbone.View.extend
tagName: "li"
className: "result"
events:
...
简短说明:
ul#results
li.result
,创建了一个元素li.result
(默认的Backbone行为) 这是(简化)我用来呈现搜索结果的模板:
<li class="result">
<h1>
<a href="{{link}}">{{title}}</a>
</h1>
<p>{{snippet}}</p>
</li>
这是我的难题,你可能已经发现了自己:我在Backbone ResultView 和我的模板中定义了一个li.result
。 我做不到的事:
li.result
,因为它在DOM中尚不存在 li.result
,因为我仍然需要它为那些没有启用JavaScript的人呈现页面服务器端 有没有办法(优雅地)在实例化后将一个Backbone视图重新分配给一个元素? 或者简单地说,我可以将ResultView引用到临时元素,渲染模板然后将其移动到ul#result
吗? 或者我是以错误的方式看待它?
谢谢!
我建议只从视图中触发渲染事件,然后在onRendered回调中执行操作,如下所示:
initialize: function() {
this.bind('rendered', onRendered);
},
onRendered: function() {
// do onRendered stuff
// eg. remove an element from the template
},
render: function() {
// your render stuff
this.trigger('rendered');
}
我发现当你试图支持服务器端渲染视图和客户端视图时,事情总会变得复杂一些。 您在这里描述的场景就是一个很好的例子。
如果可能的话,我会将页面的呈现移动到客户端,这将极大地帮助简化代码。
话虽这么说,如果你确实想要保持服务器呈现的视图,我可能会在页面加载后从你的集合上执行fetch()以从服务器获取所有对象。 然后,您可以调整ResultView初始化函数以执行以下检查。
ResultView = Backbone.View.extend
initialize: (attributes) ->
exisitingElement = $('result_' + attributes['id'])
if exisitingElement?
@el = exisitingElement
@delegateEvents()
然后,您将更改模板以包含唯一ID。
<li id="result_{{id}}" class="result">
<h1>
<a href="{{link}}">{{title}}</a>
</h1>
<p>{{snippet}}</p>
</li>
这样,ResultView将在向页面呈现新元素之前查找现有元素。 在重新分配@el属性后手动调用delegateEvents()可确保您定义的任何事件仍然有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.