我一直在阅读和研究,但我很难弄清楚如何为主干/木偶项目组织嵌套的复杂视图。在一个复合视图中的两个集合中的答案与我认为需要的非常接近,但在处理其中一个集合项中的多个视图时,它似乎有不足之处。
我将通过扩展这个问题的答案来解释。
假设我们有一套公寓,一套他们的房间,列出了他们的椅子。此外,让我们添加公寓租户。作为租户视图的想法可以有自己的视图管理、事件,并且可以在站点的其他地方重用。
根据我的理解,它可能看起来像:
我的问题是ApartmentView不允许多个子视图。
@scott-puleo提供的答案副本,并添加了租户。
var apartments = [
{apartment: '1a',
rooms: [
{name: 'master bed', chairs: []},
{name: 'kitchen', chairs: [
{chairType: 'stool'}, {chairType: 'stool'}]},
{name: 'living room', chairs: [
{chairType: 'sofa'}, {chairType: 'love seat'}]}],
tenant:{name:Bob Jones,phone:6165551234}
},
{apartment: '2a',
rooms: [
{name: 'master bed', chairs: []},
{name: 'kitchen', chairs: [
{chairType: 'shaker'}, {chairType: 'shaker'}]},
{name: 'living room', chairs: [
{chairType: 'sectional'}]}]
tenant:{name:Hope Smith,phone:6365551234}
}];
var chairModel = Backbone.Model.extend({});
var roomModel = Backbone.Model.extend({
initialize: function(attributes, options) {
this.chairs = new Array();
_.each(attributes.chairs, function(chair){
this.chairs.push(new chairModel(chair));
}, this);
}
});
var ApartmentModel = Backbone.Model.extend({
initialize: function(attributes, options) {
this.rooms = new Array();
_.each(attributes.rooms, function(room){
this.rooms.push(new roomModel(room));
}, this);
}
});
var ApartmentCollection = Backbone.Collection.extend({
model: ApartmentModel
});
var ChairView = Backbone.Marionette.ItemView.extend({
template:'#chair'
});
var TenantView = Backbone.Marionette.ItemView.extend({
template:'#tenant'
});
var RoomView = Backbone.Marionette.CompositeView.extend({
template: '#room',
itemViewContainer: 'ul',
itemView: ChairView,
initialize: function(){
var chairs = this.model.get('chairs');
this.collection = new Backbone.Collection(chairs);
}
});
var ApartmentView = Backbone.Marionette.CompositeView.extend({
template: '#appartment',
itemViewContainer: 'ul',
itemView: RoomView, // Composite View
initialize: function(){
var rooms = this.model.get('rooms');
this.collection = new Backbone.Collection(rooms);
}
});
var ApartmentCollectionView = Backbone.Marionette.CollectionView.extend({
itemView: ApartmentView // Composite View
});
apartmentCollection = new ApartmentCollection(apartments);
apartmentCollectionView = new ApartmentCollectionView({
collection: apartmentCollection
});
App.apartments.show(apartmentCollectionView);
我觉得我应该考虑为每个公寓启动单独的布局或控制器,但这不是有效的,我也不认为这是他们的目的。这些也可能使在区域中管理ID变得棘手。
谢谢你的指导,我会更新我可能发现的任何答案。
我最终找到的答案是使用LayoutView,在本例中是针对ApparationView的。LayoutView扩展了ItemView,因此也使用了模型。但除此之外,它们还支持多个区域,这些区域可以包含任何类型的视图(ItemView、CollectionView、CompositeView、LayoutView)。
基本上,每当您有一个需要多个兄弟级别视图(无论类型如何)的级别时,它们都可以包装在一个LayoutView中。
关于事件和视图之间通信的快速注释,因为这很快变得有趣。木偶相信自上而下的事件倾听。那就是父母可以听孩子的话,但是孩子应该能够独立运行,不需要听父母的话。
因此,当一个事件发生在一个兄弟姐妹需要做出反应的视图中时——父母应该监听孩子的事件...然后触发或调用另一个需要做出反应的孩子的函数。
或者,可以设置父级的模型,然后子级可以设置值,其他视图可以监听更改事件。
您的设置将非常复杂,但这些都是开始的想法。
根据我的经验,这是不同类型木偶视图的细分:
由于租户不是独立的主干模型,而是公寓的一部分,所以它被序列化并传递到ApartmentView中,因此可以直接呈现。
只有更改所需的工作是在模板:
<script type="text/html" id="apartment">
<div>
<h2>Apartment: <%=apartment%></h2>
<ul></ul>
<b><%= tenant.name %>, <%= tenant.phone %></b>
</div>
</script>
小提琴:http://jsfiddle.net/re7x2vas/