Backbone is a Javascript library that provides a clean way to:
- define models in Javascript.
- deal with Collections using a rich API.
- define Views with declarative event handling and template support.
- interface to Rest architectures.
In current post I am going to use the
Rest WebApp of my old
post, where I only explained the
server side to show you how to implement client side using
Backbone.
So the first thing to do is create a web structure into
IDE, for this example I will reuse same project of
RestServer post.
Then download
backbone.js and its dependencies and copy to
webapp/resources/js directory:
Open servlet-context.xml and add root and js folder as static resource.
Then go to webapp/resources and create index.html.
Add all Javascript libraries into page, but most important, add them in the same order as appears here, if not, some Javascript failures would appear in your browser and the application will not work.
Note that some content is created directly using HTML tags rather than using Backbone views. Normally page layout, headers, footers ... are treated as static content and they are directly written into page.
Let's start modeling our data, in this case a character with its attributes (id, name, url, isHuman...).
Models in Backbone has a particularity that make them useful, they are an implementation of Active Record pattern, so when you are creating a model you will have CRUD operations against a Rest-WebService. So for example when you call save method of your model, Backbone converts that model to JSON and sends the result to server as HTTP POST (if model has no id), or HTTP PUT (update). Other available operations are fetch (load) and destroy (delete).
See how in this case we have created a Character model setting urlRoot property. This property is used to build endpoint to ResetServer. As long as the endpoint returns JSON for a single character, properties will be merged into model.
And the same applies to Collections. When you call fetch method of characters var, all characters returned by calling GET .../characters will be stored into.
See how easy is implementing a Rest Client using Backbone. And I suppose you are wondering where are attributes' definition? Don't worry, with Backbone is not necessary to explicitly define at definition time.
Now it is time for Views. As I cited at the begin of post, Backbone has template support. For this example two templates are going to be used, one for filling a new character and another for showing character information.
To define a template you must use <script> tag with text/template type instead of text/javascript and an id. The structure is similar to JSP (embedded HTML code, <%= %> for printing variables and <% %> for logical structures).
Next step is creating Views.
For this example we are going to create three views, one for each template, and one that will be a composition of both.
Let's start with View responsible of showing information of one character.
At line 3 we are loading template content defined previously with id show-characters, into showCharactersTemplate object.
Next important line is number 6. There we are defining a function that will be invoked each time we want to render a view (one time per character). See how we are passing a model object (trust me it is not defined yet, but will be there), to template. To fill template variables, template engine requires data in JSON format, and Backbone model has a toJSON method. And finally generated html code is saved into el attribute.
Next View is responsible of showing character form, and deal with submit action.
This
View shows events handling in
Backbone. See line 9. We are defining that when user clicks on tag element "
a" with class
submit, element defined in
new-character template,
createOnEnter function is executed.
createOnEnter method does three things:
- gets values from template form.
- instantiates CharacterModel class. See that this is the place where model attributes are defined.
- calls save method. This method sends object data to defined endpoint at server side. Because this operation is asynchronous, a callback is registered, so when a success is received, character is added into characters list.
And last
View is a composite view of two previous views, acts as a controller between adding a new
character and showing all inserted
characters:
Initialize function does all required initializations so
UI could be refreshed asynchronously. In first two lines we are binding
add and
reset functions of
characters collection to a method. For example each time
add function is called,
addCharacter is invoked.
Next line is used to populate data to
Collection. When
fetch is called an
HTTP GET to defined endpoint is sent, data is retrieved and
Collection's add method is called for each result.
addCharacter function is responsible of creating one
View for each character. There is not much secret, we are creating a
CharacterView, and appending the result of calling its render method to
html element with
character-list id.
And finally
render function that is responsible of rendering
CharacterFormView.
See that page is only loaded first time we access it, subsequent updates are done by
DOM manipulations.
To finish I embedded all
html file explained here so you can see a global overview of all pieces used. Also feel free to download all
Eclipse project. I wish you find this post useful.
Download Code
Music:
http://www.youtube.com/watch?v=q1Ebi9cSn48