Skip to content

Instantly share code, notes, and snippets.

@ynonp
Last active December 11, 2015 02:38
Show Gist options
  • Save ynonp/4531578 to your computer and use it in GitHub Desktop.
Save ynonp/4531578 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Nested BB</title>
</head>
<body>
<script type="text/template" id="mbox">
<h1>{{title}}</h1>
<div id="messagesView">
</div>
</script>
<script type="text/template" id="messages">
<ul>
{{#each messages}}
<li>{{subject}}</li>
{{/each}}
</ul>
</script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.rc.1/handlebars.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<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.9/backbone-min.js"></script>
<script src="main.js"></script>
</body>
</html>
// A mailbox HAS many messages
// Message is a model having from and subject fields
var Message = Backbone.Model.extend({});
// Glued in a Messages collection
var Messages = Backbone.Collection.extend({
model: Message
});
// Create two global messages (you'd usually take these from the server)
var m1 = new Message({ from: 'me', subject: 'Hello' });
var m2 = new Message({ from: 'you', subject: 'Bye Bye'});
// The outer model (Mailbox) has a title field,
// and a messages attribute
var Mailbox = Backbone.Model.extend({
initialize: function() {
// messages is initialized empty
this.messages = new Messages();
// later we'll fetch the messages collection from the server
// using this url
this.messages.url = '/mailbox/' + this.id + '/messages';
}
});
// The models are rendered using two views
// MessagesView is the inner view, so it simply renders its collection
// using a template
var MessagesView = Backbone.View.extend({
render: function() {
this.$el.html( this.template( { messages: this.collection.toJSON() } ) );
return this;
},
template: Handlebars.compile( $('#messages').html() )
});
// MailboxView is the more complex being the outer view
// It needs to render itself AND its inner view, and it also
// creates the inner view
var MailboxView = Backbone.View.extend({
tagName: 'div',
className: 'mbox',
initialize: function() {
// Creating the inner view and providing it with the data
this.innerView = new MessagesView({ collection: this.model.messages });
this.model.messages.bind('change', this.renderInner, this);
this.model.messages.bind('reset', this.renderInner, this);
},
render: function() {
// first render myself
this.$el.html( this.template( this.model.toJSON() ) );
return this;
},
renderInner: function() {
// then find the inner view hook
var innerEl = this.$el.find( '#messagesView' );
this.innerView.setElement( innerEl );
this.innerView.render();
return this.innerView;
},
template: Handlebars.compile( $('#mbox').html() )
});
// Create the main model
var Inbox = new Mailbox({ title: 'Inbox'});
// Create the main view
var v = new MailboxView({ model: Inbox });
// and render it to the body
$('body').append( v.render().el );
// And fill it with data (can also fetch() from the server)
Inbox.messages.reset([m1, m2]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment