Backbone.js: Nested model
by kwon
HTML
<script src="http://documentcloud.github.com/underscore/underscore.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone.js"></script>
<script src="http://documentcloud.github.com/backbone/examples/backbone-localstorage.js"></script>
<script src="https://raw.github.com/PaulUithol/Backbone-relational/master/backbone-relational.js"></script>
<section id="restaurant_menu">
<h1>Menu for <span class='restaurant_name'></span></h1>
<button class="new_menu_type">New Menu Type</button>
<ol class="menu_types"></ol>
</section>
<section class="form_views"></section>
<script type="text/html" id="menu_type_item_tpl">
<h1>Menu Item</h1>
<nav>
<a href="#" class="new_menu_category">Add Menu Category</a>
|
<a href="#" class="destroy_type">X</a>
</nav>
<ol class="menu_categories"></ol>
</script>
<script type="text/html" id="menu_category_item_tpl">
<h1>Menu Category</h1>
<nav>
<a href="#" class="new_menu_item">Add Menu Item</a>
|
<a href="#" class="destroy_category">X</a>
</nav>
<ol class="menu_items"></ol>
</script>
<script type="text/html" id="menu_item_item_tpl">
<h1>Menu Item</h1>
<nav>
<a href="#" class="destroy_item">X</a>
</nav>
</script>
<!-- form templates -->
<script type="text/html" id="new_menu_type_tpl">
<h1>New Menu Type</h1>
<input type="text" name="menu_type_name" />
<button>Save</button>
</script>
<script type="text/html" id="new_menu_category_tpl">
<h1>New Menu Category <span class="menu_type_name"><span></h1>
<input type="text" name="menu_category_name" />
<button>Save</button>
</script>
<script type="text/html" id="new_menu_item_tpl">
<h1>New Menu Item <span class="menu_category_name"><span></h1>
<input type="text" name="menu_item_name" />
<button>Save</button>
</script>
SCSS
ol {
list-style-type: decimal;
margin-left: 25px;
}
#restaurant_menu {
float: left;
width: 50%;
height: 350px;
overflow-y: auto;
}
.form_views {
background-color: #efefef;
float: left;
width: 50%;
}
JavaScript
// Models
var Restaurant = Backbone.Model.extend({
localStorage: new Store("restuarant"),
initialize: function() {
this.menu_types = new MenuTypes();
},
parse: function(response) {
console.log('parse');
return response;
}
});
var MenuType = Backbone.Model.extend({
localStorage: new Store("menutypes"),
initialize: function() {
this.menu_categories = new MenuCategories;
}
});
var MenuCategory = Backbone.Model.extend({
localStorage: new Store("menucategories"),
initialize: function() {
this.menu_items = new MenuItems;
}
});
var MenuItem = Backbone.Model.extend({
localStorage: new Store("menuitems")
});
// Collection
var MenuTypes = Backbone.Collection.extend({
model: MenuType,
localStorage: new Store("menutypes")
});
var MenuCategories = Backbone.Collection.extend({
model: MenuCategory,
localStorage: new Store("menucategories")
});
var MenuItems = Backbone.Collection.extend({
model: MenuItem,
localStorage: new Store("menuitems")
});
// initialize collections
//var menu_types = new MenuTypes;
//var menu_categories = new MenuCategories;
// Line views
var MenuTypeView = Backbone.View.extend({
tagName: "li",
template: _.template($("#menu_type_item_tpl").html()),
events: {
'click .new_menu_category': 'new_menu_category',
'click .destroy_type': 'destroy'
},
initialize: function() {
this.model.bind('destroy', this.remove, this);
this.model.menu_categories.bind('add', this.add_menu_category, this);
this.render();
},
render: function() {
$(this.el).html(this.template());
this.$("h1").text(this.model.get('name'));
return this;
},
new_menu_category: function(evt) {
console.log("new menu category...");
var form = new MenuCategoryFormView({
model: new MenuCategory({menu_type: this.model})
});
...