I've been reading and researching, but I'm having trouble figuring out how to organize nested complex views for a Backbone/Marionette project. The answer in Two Collections inside a Composite View is very close to what I believe is needed, but it seems to fall short when it comes to handling multiple views in one of the collection items.
I'll explain by extending apartment example answer in that question.
Let's say we have a collection of apartments, a collection of their rooms, listing their chairs. In addition lets add in the apartment tenant. The idea being a tenant view could have it's own view management, events, and be reused elsewhere on the site.
From my understanding it might looks something like:
- ApartmentCollectionView (CollectionView)
- ApartmentView (CompositeView)
- TenantView (ItemView)
- RoomView (CompositeView)
- ChairView (ItemView)
- ApartmentView (CompositeView)
My problem being that the ApartmentView doesn't permit multiple sub views.
Copy of answer provided by @scott-puleo with addition of Tenants.
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);
I feel I should be looking at initiating individual Layouts or Controllers for each of the Apartments, however can't be efficient, nor do I think that is what they are intended for. Those also might make it tricky to manage the ids in regions.
Thanks for any direction, I'll update with any answers I may uncover.