Javascript 将主干视图重新分配给新创建的DOM元素
我正在创建一个搜索结果页面,将主干网与咖啡脚本和把手结合使用。我有两个视图:一个用于结果列表(ListView),第二个视图用于单个结果(ResultView)。简化代码:Javascript 将主干视图重新分配给新创建的DOM元素,javascript,backbone.js,Javascript,Backbone.js,我正在创建一个搜索结果页面,将主干网与咖啡脚本和把手结合使用。我有两个视图:一个用于结果列表(ListView),第二个视图用于单个结果(ResultView)。简化代码: ListView = Backbone.View.extend el: $("ul#results") ... addItem: (result) -> resultView = new ResultView({ model: result }) 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#结果
- 将结果添加到listview时,将创建一个ResultView,该视图了解其父视图并呈现自身
- 对于结果视图,将创建元素
(默认主干行为)li.result
<li class="result">
<h1>
<a href="{{link}}">{{title}}</a>
</h1>
<p>{{snippet}}</p>
</li>
{{snippet}}
这是我的难题,您可能已经发现了:我在我的主干ResultView和模板中定义了一个li.result
。我不能做的是:
- 将ResultView绑定到我的模板中的
,因为它在DOM中还不存在li.result
- 从我的模板中删除
,因为我仍然需要它来为那些没有启用JavaScript的人呈现页面服务器端li.result
ul#result
?还是我看错了
谢谢 我发现,当您尝试支持服务器端渲染视图和客户端视图时,事情总是会变得更加复杂。您在这里描述的场景就是一个完美的例子 如果可能的话,我会将页面的呈现移到客户端,这将大大有助于简化代码 也就是说,如果您确实希望保留服务器呈现的视图,我可能会在页面加载后对集合执行fetch(),以从服务器获取所有对象。然后可以调整ResultView initialize函数以执行以下检查
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>
{{snippet}}
这样,ResultView将在向页面呈现新元素之前查找现有元素。重新分配@el属性后手动调用delegateEvents(),可确保您定义的任何事件仍能工作。我建议您只需从视图中触发渲染事件,然后在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');
}
谢谢你的回复,但我认为这并不能解决我的问题;元素是在渲染后创建的,因此“existingElement”永远不会发生。但也许我想要的东西做不到(有点像第二十二条军规),所以我还是要看看你的建议。谢谢你!我实际上把你的答案和斯科特·哈维的答案结合起来了;我使用了render触发器,重新分配了新的
li.result
,然后使用@delegateEvents确保事件被绑定。