I got turned on to Backbone.js this week. It has a good name and is used on a lot of high profile projects, such as Basecamp Mobile, SoundCloud Mobile and Groupon Now! To-do lists seem like a popular example, and for good reason: it's good way to expose the different elements of this framework. So why not try to make a to-do list from scratch? Four hours later, I had something acceptable.
Click here for the full demo.
Models
ToDo ModelThe first thing to do was to create the atomic model for a to-do item. The to-do idem should have a title and a completed state (true if completed, false if not).
/* * Set up to-do model */ ToDo = Backbone.Model.extend({ //define model default values defaults: { title: "To Do", completed: false } }); //create a dumy to do item var toDo = new ToDo({ //override model default values title: "False" });
Already, I can see advantages over using raw Prototype objects. The syntax is terse, which is always a good thing. A terse syntax is easier to learn, easier to read and exposes errors more readily than a verbose one. Secondly, constructor definition isn't required; there is a standard constructor that handles basic operations that don't need to be recreated. Finally, model constructor takes in an object to override default values. Anyone familiar with jQuery plugins can appreciate the utility of this method; it obviates the necessity of passing multiple parameters to a constructor.
ToDoList Model
Before I move on to the List model, I created a Todo Collection. A Collection is another Class in Backbone that can be seen as a rich array containing objects of a Model type. In this case, I created a collection to hold ToDos.
/* * Collection of ToDos Models */ ToDoCollection = Backbone.Collection.extend({ model: ToDo //only accept ToDos });
Easy. On to the ToDoListModel definitions. In this case, a ToDoList will have a title and a ToDoCollection. It will also have an instance method for adding a ToDo to the list.
/* * Model for the ToDo List */ ToDoList = Backbone.Model.extend({ defaults:{ toDos: new ToDoCollection(), title: "Untitled" }, addToDo: function(toDo){ this.get("toDos").add(toDo); //reference toDos collection and add the new toDo } });
This brings up one of the few things I don't like about Backbone: Attributes of a model are accessed by passing a string to the get function. (see. line 10 above). However, this is unavoidable when considering a crucial feature of Backbone that I will be covering later.
Views
Views in Backbone are a lot like ViewControllers in UIKit. They reference the html element the view is tied to, and handle event from the element and its descendants. Additionally, the view can be tied to a specific model, this can be very useful. Below is a skeleton Backbone view.The views used in the ToDo List are much longer than needed for exposition. The final implementation can be seen here.
ToDoView
ToDoView = Backbone.View.extend({ initialize: function(){ //do stuff with the model if you want this.model; //reference to the views model this.render(); }, render: function(){ //create and fill in the view this.el; //reference to the html element this.$el; //reference to the jQuery object for this view }, //object containing events and listeners events{ "click a" : "doLinkClick" }, //click listener doLinkClick: function(){ //respond to click } }); var v = new ToDoView({ el: document.getElementByID("element_id"), //this can also be a jQuery object, model: new ToDo() // start the skeleton view with a model });
Binding to model events
A great feature of Backbone (one that it shares with Knockout.js), is the ability to bind events to the attributes of a model. For example, when the value of an attribute is changed, an event is fire. The view can then bind listeners to these events.
ToDoView= Backbone.View.extend({ initialize: function(){ var t = this; this.model.bind("change:title", function(){ t.onToDoTitleChange(); }); }, onToDoTitleChange: function(){ //do stuff on title change } });
Briefly On Templates
The concept of templates is implemented by at least a couple of javascript frameworks, Templates are not a feature of Backbone, but rather one of its dependencies (Underscore.js). Regardless, templates are very helpful.What you do with templates is load a template of html and define places where attributes of the model are inserted into the markup.
In this case the template generator inserts the model's title into the list element markup as text. Attributes can also be inserted anywhere in the markup. Templates are awesome.
I love underscore.js. I used it a long time ago around the time we started using jQuery full time.
ReplyDelete