lunes, enero 02, 2012

Sábado na balada, A galera começou a dançar, E passou a menina mais linda, Tomei coragem e comecei a falar (Ai se eu te pego - Michel Teló)

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


Donate If You Can and Find Post Useful