We are launching a new mobile web interface for Harvest today. It introduces a redesigned mobile time tracking interface and a new Team Status page, both of which are kept up to date regardless of updates being made on other devices. It is also technically implemented differently than most of the Harvest UI. We wanted to experiment with some cutting-edge technologies, and this is the result!
Models are the basic objects the application operates upon. In Harvest’s case, one such Model could be
Project. Usually there is a 1:1 mapping between the Backbone Models and backend Models (database tables), but this is not strictly necessary. For example, on the frontend we have a
RecentProjectTask Model used to ease project task selection that does not have a direct match in the database.
The best part about Backbone Models is actually related to another Backbone feature called Events and how they interact with Views. In a framework like Rails, a Model is a passive object that gets operated on by a controller or perhaps another Model. Backbone Models, on the other hand broadcast events that are processed by Views subscribing to them. There is a useful decoupling between action and reaction.
Collections are a set of Models basically corresponding to a set of rows in a backend database, though again this need not be so. They also have the same Event love that Models have.
Views are responsible for presenting the user interface and responding to user events. For this reason Backbone Views, are more than just passive string generators. In fact, as a best practice, the HTML for the user interface should be stored in Templates instead. The choice of how Templates are implemented is not determined by Backbone. Unlike some opinionated frameworks, not much is set in stone by Backbone.
Beside being able to react on events, the next best thing about Views is the ability to nest them. This nesting drives the structure of the code starting from the UI mockup, for example:
This screen suggests at least three different kinds of Views. First, there is the top container responsible for the header, the navigation to other days, the opening of the menu, etc. Second, there is the View shown in pink that draws out all the entries. This View is tied to a Backbone Collection.
On the third level, there are small individual Views tied to each entry present on the screen. Some of these are outlined in blue in the above picture. Nesting occurs naturally, the top container View creates the next level of Views below. The containing view may also referrences to its child Views in instance variables, but this is usually no necessary. The a nested View takes on an active role and does not strictly need to be operated on by its parent.
For example, when you delete timesheet entry the corresponding View (outlined in blue above) will get notified via a
destroy event and will have the opportunity to remove itself accordingly. The deleted timesheet entry was part of a Collection that also gets notified, which in turn notifies the containing View, ultimately allowing a different Total Hours value to be displayed on screen. Control can flow entirely through events without needing instance variables.
It Is a Sour Cherry
The advantage of using a framework like Backbone is its ordered method for creating fluid interactions. Ajax made partial screen updates possible, but making this fluid is difficult if you’re rendering parts of the UI on the backend.