Dynamic ItemView for CollectionView
In answer to http://stackoverflow.com/questions/22442472/backbone-designing-an-html-designer-app
HTML
<body>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.marionette/1.5.1-bundled/backbone.marionette.min.js"></script>
<div id="container"></div>
</body>
CSS
.block {
background: #ddd;
padding: 1em;
display: block;
}
.inline {
display: inline-block;
padding: 1em;
background: #eee;
border: 1px solid black;
}
JavaScript
// A basic model to represent each element
var ElementModel = Backbone.Model.extend({
defaults: {
tagName: 'div',
display: 'block'
}
});
var Collection = Backbone.Collection.extend({
model: ElementModel
});
// A view for all inline elements
var InlineItemView = Marionette.ItemView.extend({
className: 'inline',
template: _.template('I\'m a <%= tagName %> inline element')
});
// A default view of all block elements
var BlockItemView = Marionette.ItemView.extend({
className: 'block',
template: _.template('I\'m a <%= model %> block element')
});
// Our collection view which will determive which view type to
// render for each model
var CollectionView = Marionette.CollectionView.extend({
// Determine the default view for each item.
itemView: BlockItemView,
// Dynamically change the item view for each model as needed
buildItemView: function(item, ItemViewType, itemViewOptions){
// build the final list of options for the item view type
var options = _.extend({
model: item,
tagName: item.get('tagName')
}, itemViewOptions);
var view;
// Change the item's view based on the options...
if(item.get('display') === 'inline') {
view = new InlineItemView(options);
}
else {
// defaults to BlockItemView
view = new ItemViewType(options);
}
return view;
}
});
var collection = new Collection([{
tagName: 'h1'
},{
tagName: 'h4',
},{
tagName: 'div'
},{
tagName: 'span',
display: 'inline'
},{
tagName: 'p',
display: 'inline'
}]);
var collectionView = new CollectionView({
collection: collection
});
$('#container').append(collectionView.render().el);