Backbone.js and RESTful web services
One of the more interesting things about Backbone.js is its integration with RESTful web services.
Let’s say I have the following web services:
| URL | Verb | Description |
|---|---|---|
| /entities | GET | fetch entities |
| /entities | POST | create entity |
| /entities/id | PUT | modify entity |
| /entities/id | DELETE | delete entity |
And that each service takes JSON objects or arrays of objects, where each object has the following properties (with sample values):
{
id: 1 // not needed for POST
name: 'my name'
}
You can see that this is exactly what Backbone.js expects.
I knocked the service up in Django, then wrote the following front-end app to demonstrate it. Notice the use of jQuery templates.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Backbone.js REST Support Demo</title>
</head>
<body>
<p><input id="new-name" type="text"><button id="add">Add</button></p>
<div id="entities"></div>
</body>
<script id="entity-template" type="x-jquery-tmpl">
<input type="text" value="${name}">
<button>Delete</button>
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script src="{{ STATIC_URL }}underscore-min.js"></script>
<script src="{{ STATIC_URL }}backbone-min.js"></script>
<script src="{{ STATIC_URL }}rest.js"></script>
</html>
/*global Backbone, $, _ */
var Entities = {};
Entities.Collection = Backbone.Collection.extend({
url: '/entities'
});
Entities.Views = {};
Entities.Views.Edit = Backbone.View.extend({
change: function () {
this.model.set({
name: $(this.el).children('input').val()
});
this.model.save();
},
destroy: function () {
var el = this.el;
this.model.destroy({
success: function () {
$(el).remove();
}
});
},
events: {
'click button': 'destroy',
'change input': 'change'
},
initialize: function () {
_(this).bindAll('change', 'destroy', 'render');
},
render: function () {
$('#entity-template').tmpl(this.model.toJSON()).appendTo(this.el);
this.delegateEvents();
}
});
Entities.Views.List = Backbone.View.extend({
append: function (model) {
var p = $('<p>').appendTo('#entities'),
view = new Entities.Views.Edit({
model: model,
el: p[0]
});
view.render();
},
initialize: function () {
_(this).bindAll('append', 'render');
this.collection.bind('refresh', this.render);
this.collection.bind('add', this.append);
},
render: function () {
$('#entities').empty();
this.collection.each(function (model) {
this.append(model);
}, this);
}
});
$(function () {
var collection = new Entities.Collection(),
view = new Entities.Views.List({
collection: collection
});
collection.fetch();
$('#add').click(function () {
var model = new Backbone.Model({
name: $('#new-name').val()
});
collection.add(model);
model.save();
});
});