技术上是否可以使用模板来嵌套视图:
<%= new PhotoCollectionView({model:new PhotoCollection(model.similarPhotos)}).render().el) %>
我也可以将所有内容都放在渲染方法中,但模板为灵活性和布局提供了更多空间。
我尝试了上述变体,但我在屏幕上得到的结果是[HTMLDivElement]
。
如果我尝试仅提取HTML,使用jQuery的HTML,我会将其渲染,但事实证明,打印出来的DOM节点与视图引用的DOM节点不同,因为使用视图实例,无法与这些DOM节点进行任何交互。例如,如果在视图中我说$(this.el).hide()
,则不会发生任何事情。
什么是正确的方法,如果有的话?
答案 0 :(得分:29)
我通常首先渲染父视图。然后我使用this.$('selector')
方法查找一个可以用作子视图el的子元素。
以下是一个完整的例子:
var ChildView = Backbone.View.extend({
//..
})
var ParentView = Backbone.View.extend({
template: _.template($('#parent-template').html()),
initialize: function() {
_.bindAll(this, 'render');
}
render: function() {
var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView.
return this;
}
});
var v = new ParentView();
v.render();
答案 1 :(得分:14)
接受的答案有一个重大缺陷,即每次渲染时都会重新初始化ChildView。这意味着您将丢失状态,并且可能必须在每个渲染上重新初始化复杂视图。
我在这里写了一篇博客:http://codehustler.org/blog/rendering-nested-views-backbone-js/
总结一下,我建议使用这样的东西:
var BaseView = Backbone.View.extend({
// Other code here...
renderNested: function( view, selector ) {
var $element = ( selector instanceof $ ) ? selector : this.$el.find( selector );
view.setElement( $element ).render();
}
});
var CustomView = BaseView.extend({
// Other code here...
render: function() {
this.$el.html( this.template() );
this.renderNested( this.nestedView, ".selector" );
return this;
}
});
如果你不想扩展Backbone视图,可以将renderNested方法放在你喜欢的任何地方。
使用上面的代码,您现在可以在初始化方法中初始化ChildView,然后在调用render()时简单地渲染它。
答案 2 :(得分:2)
查看Backbone.Subviews mixin。它是一个用于管理嵌套视图的极简主义mixin,并且不会在每次呈现父级时重新初始化子视图。
答案 3 :(得分:1)
我不知道模板本身,但我以前用表和列表完成了。在外部模板中,只有stub:
<script type="text/template" id="table-template">
<table>
<thead>
<th>Column 1</th>
</thead>
<tbody>
</tbody>
</table>
</script>
以及个别项目: &lt;%= field1%&gt;
然后在你的渲染方法中,只渲染单个项目并将它们附加到tbody元素......
答案 4 :(得分:-1)
每次渲染时初始化一个新对象的决定在我看来效率很低。 特别是:
render: function() {
var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView.
return this;
}
理想情况下,父级的渲染应该类似于
render: function() {
this.$el.html(this.template());
this.childView1.render();
this.childView2.render();
}
只有在初始化父级时才会创建子级:
initialize: function() {
this.childView1 = new ChildView1(selector1);
this.childView2 = new ChildView2(selector2);
}
问题是我们在渲染父模板之前没有selector1和selector2。这就是我现在陷入困境的地方:)