Routeless Backbone Contacts 2.0

Published: 2011-10-03
Updated: 2011-10-25

This post describes a revamped version 2.0 of my original Routeless Backbone Contacts application. The material covered here builds on the original post.

  1. The basic application functionality and the underlying data remains the same.
  2. The new user interface is a single two-pane page with a selectable list of contacts on the left and contact details on the right.
  3. A Search box has been added to incrementally filter the list of displayed contacts.
  4. The application is 100% event driven — there is no direct coupling between the views. Backbone.js events emitted by the underlying contact data collection ensure the views are updated automatically when the state of the underlying data changes.

Routeless Backbone.js Contacts is a totally client-side CRUD tutorial application written using CoffeeScript, Stylus, Backbone.js and jQuery which are a perfect match for writing concise, readable well structured web applications.


User Interface

contacts2-screenshot.png

The single page user interface combines four Backbone.js views. The views subscribe to, and are updated by, events emitted by the contacts collection (add, remove, change, reset, filter, select).


Models and Collections

ContactModel

The same model as version 1.0.

ContactsCollection

The ContactsCollection collection has been enhanced:

  1. The Filter class provides functions to filter the collection by contact name. When the filter criteria changes the collection broadcasts a custom filter event to subscribed views.
  2. The Cursor class provides a cursor object which represents the currently selected model in the contacts collection. The cursor listens for changes to the collection so that it can automatically ensure the cursor points to a valid contact in the filtered collection. When the cursor changes the contacts collection broadcasts a custom select event to subscribed views.

Views

RibbonView

contacts2-ribbon.png

StatusView

contacts2-status.png

ListView

contacts2-list.png

DetailView

contacts2-detail.png

Browser Compatibility

The markup generated by this tutorial is HTML5 with CSS3, no attempt has been made to accommodate legacy browsers.

  • Was developed and tested on Google Chrome 14.
  • Firefox 6 works fine.
  • Requires IE9+ for correct CSS styling (though the header gradient doesn’t work in IE9).
  • Requires iOS5+ for the names list to scroll.

Backbone.js Tips

  • The use of the fat arrow function definition operator in event handlers is significant. In the following example, when render is called this will be bound to the callee’s this context so the reference to @el will be correct:
      @model.bind 'change', @render
      render: =>
          @el.html @template
  • Don’t rely on the execution order of registered events.
  • The Model change event bubbles up through related collections.
  • It pays to monitor event handler execution during development. If a section of code triggers the execution of the same handler multiple times this may be symptomatic of a non-optimal design. For example, without the silent option the following code would trigger multiple collection remove events (the collection reset is sufficient to ensure listener notification):
    contact.destroy {silent: true} for contact in @collection.toArray()
    @collection.reset()

    On the other hand, it’s not unusual for event handlers to execute common code which can also result in execution redundancy (for example, the renderCursor handler is also called by the render handler in the ListView). In cases like this don’t sweat over eliminating the redundancy unless it impacts performance — code clarity is usually preferable to the convoluted and brittle optimisations generated by a “fix”.

  • When Backbone.js Models and Collections emit built-in events they pass associated event information to the event handler arguments. The catalog of Backbone.js events documents the event handler arguments. Currently undocumented is fact that options arguments passed to event triggering methods are passed through to the handlers as the trailing argument. In the following example an object containing a custom option myOption will be the third argument passed to the add event handlers "add"(model, collection, options):
    myCollection.add myModel, {myOption: 'foobar'}
  • Don’t forget that Backbone.js event handlers are passed arguments (see previous item). For example, the Backbone.js Collection reset event passes the associated collection to the handler in the first argument which will cause the following code to fail:
    @_collection.bind 'reset', @set
    set: (model=null) =>
        :

    If you assumed that the set handler would be called with no arguments you would expect model to be set to null — in fact model is assigned @_collection. The code can be fixed by introducing an anonymous proxy handler that is bound to this and called without any arguments:

    @_collection.bind 'reset', => @set()
    set: (model=null) ->
        :
  • Use the built-in event argument passing conventions if you have to trigger a built-in event programmatically. For example:
    @collection.trigger 'reset', @collection
About these ads

One Response to “Routeless Backbone Contacts 2.0”

  1. Tuyet Says:

    I have been surfing online more than 3 hours today, yet I never found any
    interesting article like yours. It’s pretty worth enough for me. In my opinion, if all site owners and bloggers made good content as you did, the net will be much more useful than ever before.|
    I could not resist commenting. Perfectly written!|
    This is exactly along the same lines as my blog

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: