Backbone-nested-views
by abenrob
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.3/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<button id="addA">Add to A</button><button id="addB">Add to B</button><br>
<div id="target"></div>
CSS
button {
margin: 10px 0 0 10px;
}
table {
width: 200px;
margin: 10px;
}
tr {
border:1px solid #000;
}
tr{
display: inline-block;
width: 100%;
}
td {
padding: 5px;
}
.name {
float: left;
}
.nums {
float: right;
width: 100px;
text-align: right;
}
.hideme {
display: none;
}
.list-expand {
cursor: pointer;
}
JavaScript
var sampleData = [
{_id:"a", name: "a",nums:[{num:1},{num:2},{num:3},{num:4}]},
//{name: "b",nums:[{num:5},{num:6},{num:7},{num:8}]},
{_id:"b", name: "b",nums:[]},
];
/** Collection of models to draw */
var rowModel = Backbone.Model.extend({
idAttribute:"_id"
});
var rowsCollExtend = Backbone.Collection.extend({
model:rowModel
});
var rowsCollection = new rowsCollExtend([]);
/** View representing a table */
var TableView = Backbone.View.extend({
tagName: 'table',
initialize : function() {
_.bindAll(this,'render','renderOne');
if(this.model) {
this.model.on('change',this.render,this);
};
this.collection.on('add', this.render,this);
},
render: function() {
this.$el.empty();
this.collection.each(this.renderOne);
return this;
},
renderOne : function(model) {
var row=new RowView({model:model});
this.$el.append(row.render().$el);
return this;
}
});
/** View representing a row of that table */
var RowView = Backbone.View.extend({
initialize: function() {
this.model.on('change',this.render,this);
},
render: function() {
var template = _.template("<tr><td class='name'><%= name %></td><td class='nums'></td></tr>");
this.$el.html(template(this.model.toJSON()));
var listCollection = new Backbone.Collection(this.model.toJSON().nums);
var aList = new ListExpandView({collection:listCollection});
aList.render();
this.$el.find('.nums').append(aList.$el);
return this;
},
});
/** View representing list within row **/
var ListExpandView = Backbone.View.extend({
initialize: function() {
this.collection.on('change',this.render,this);
},
events: {
"click .list-expand": "listExpander",
},
listExpander: function(e) {
if ($(e.target).hasClass('hiding')) {
$(e.target).siblings('.item').removeClass('hideme')
...