The BackboneJS Way of Thinking

So you are frustrated tackling BackboneJS and wondering why it isn’t solving your problems as you had expected it to, after hearing about its glorious penetration in many high profile projects. Well, join the club, you are not alone. Here I’ll share my expectations when I imported BackboneJS for the first time in my project and my learning that I gained after weeks of trial and error and frustration.

Backbone is like a hammer, if you do not know what you are trying to build, the hammer will not build it for you. It does give you some powerful functions, but the burden of creating a strategy for your front-end falls on your own shoulders. But worry not, here are some ideas that might help you create your strategy.

Traditional Paradigm

If you have written jQuery plugins, or developed any other UI elements, you would know that we tend to divide a page into different UI elements. Each UI element requests the data it requires and renders it within itself. With simple apps, this strategy works, but as the complexity of an app grows, things tend to become tedious. It becomes increasingly difficult to reduce redundant data requests and maintain integrity of those UI elements which render same data.

The Paradigm Shift

BackboneJS reverses this relationship between data and UI elements, and this is what I would like to call paradigm shift. If you would try to build your app with BackboneJS and traditional paradigm you will end up creating a meatball sundae.

In a BackboneJS app, your data is the primary citizen and views are slaves. In the rest of the post, I’ll try to explain how this master-slave relationship is supposed to work.

Model Is The Backbone

“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.” – Linus Torvalds

Model is the data structure of your application, hence earns the title of “backbone”. You instantiate your Model when your application initializes, display its state through different Views, update the state through different controls and so on and so forth. Everything revolves around the Model, so take extra care to keep it clean and maintain its integrity through different checks and balances.

Views Are Secondary Satellites

A piece of UI is called a View in BackboneJS world. Views serve to:

  1. Display models
  2. Change state of models
  3. Update themselves when model state is changed

A View is usually provided with a Model (or with a Collection of Models) on instantiation, with which the View binds itself. By binding I mean that the View updates itself when some events occur in the Model. A View only acts as a mediator between the Model and the user: when a Model is updated, View delivers the information to the user by visually updating itself and delivers user’s commands back to the Model using controls.

In theory, a View should not change its own state from within itself. If a View needs to be changed,
its Model should be changed only, and the Views bound to that model, including the first View, should updated themselves consequently. Similarly a View cannot change a Model’s state unless it a command from the user. The idea forces one to place most of the business logic into the Models.

Routers Only Help Setup A Stage

Routers only allow you to setup your model on a page (URL) and instantiate some views with it. Once your stage is ready, router remains there no more, and focus should be shifted towards the model states.

Don’t Use Any Plugin Before You Know The Problem They Are Solving

BackboneJS has a huge community and it keeps on churning a new plugin every other day. Many of those plugins look shiny and claim to make your life easier. Some of them definitely succeed in making life easier but in my opinion using them prematurely could backfire and increase complexity instead of decreasing it. So they should not be touched unless you really know the problem they are trying to solve.

Core BackboneJS library is powerful enough to tackle most of the complexity so give it a try first. Simplicity is the key.

Avoid Unnecessary Server Calls

BackboneJS forces you to expose server side database through REST APIs and makes it delightfully simple to bind those APIs to frontend Models. One might be lured to make everything dynamic and fetch ALL of the data dynamically, but that is not the point of BackboneJS and it will only make your app inefficient.

A better approach would be to categorize your data into two types: one which you know you will surely need on page load and the other, whose requirement will be dependent upon different events. Use dynamic fetches for only second type of data. For first type of data, print the data in JSON format in a script tag on your HTML page through your server side HTML generator, and instantiate your Models with that JSON on page load. This way you’ll be saving some extra HTTP requests and creating a better experience for your users.

Keep It Simple

As I mentioned earlier, the whole point of using BackboneJs is to make your code cleaner and simpler while creating rich user experience at the same time. Design simple Models and simple Views. Keep Models highly independent: a View may refer a Model in its code, but a Model should not refere a View. If it is not simplifying your code, you are probably doing something wrong.

Common Steps To Design A Page

Here is a small checklist that might help when designing a page.

  1. Create your Models.
  2. Create your views (which, at this stage, should only render initial states of their Models and not change their states).
  3. Bind your Views to Model events (make sure Views update themselves when their Models’ states are updated).
  4. Test your Views (update your Model state manually through console and see how the Views respond)
  5. Create your controls (which modify model state)

Conclusion

Of course, the ideas that I discussed above are not official and I learned them through my own experience. So they might be flawed or there might be some corner cases which I missed. If you happen to see any, please do let me know. One of the motivations behind writing this post was to get a validation of my learning from more experienced folks.

On the other hand, if this post helped you solve any of your problems, please share that as well. Any other ideas/thoughts/suggestions/feedback are welcome.

Umar Ashfaq

Umar Ashfaq is a full-stack web developer. His core strengths are Java (Spring, Hibernate stack) and JavaScript (both client-side and server-side). Follow him on twitter @umarashfaq87

More Posts

Follow Me:
TwitterFacebookLinkedIn

No related posts.

16 Comments

  • 1
    garret
    April 20, 2013 - 2:20 pm | Permalink

    Nice write-up, Umar. I’ve never worked with any of the more popular SPA frameworks and I was wondering lately about how they’re structured and how they’re different. This was a nice insight into backbone.

  • 2
    April 22, 2013 - 1:59 pm | Permalink

    Hi Umar,

    interesting write-up. Additionally, what I felt was new to me when coming to backbone, was working with the Browser Console to debug parts (often models indeed) of the Backbone MVC. Indeed, the router is the just there (or not), but takes not much attention. What I find sometimes difficult though is how to distribute JSON that comes from the server in once over a number of models.

    Looking forward for further discussion.

    Patrick

    • 3
      Umar Ashfaq
      April 23, 2013 - 12:03 am | Permalink

      Thanks for the comment, Patrick.

      Router is definitely an important tool: it binds different Model states with different URLs and allows a user to directly jump upon a particular state without going through the whole process, but I feel I still need to improve my understanding about the Router, that’s why I avoided writing about it.

      About the distribution of JSON over a number of models, I guess that totally depends upon the context. Are you trying to fetch the JSON on page load and instantiate some initial models? If that is the case, then as I mentioned in the post, the better way would be to “print” the initial JSON objects/arrays onto your generated HTML and instantiate your Models right away on page load without any extra AJAX request.

      • 4
        April 23, 2013 - 12:36 am | Permalink

        Thanks, Umar, for the feedback too.

        About the Router, it’s tricky indeed to pass events across the application, and I found that using a controller/channel for cross-application events will be necessary sooner or later. See also, the discussion in this post: http://thinkingonthinking.com/organizing-a-backbone-application/

        About the pre-populating a JSON in a collection: Yes, I agree too. The point I found difficult is sometimes if your collection contains ‘meta’-data that need to be stripped away, and stored into a separate model needs some practice. I see better what you meant in your post above now.

  • 6
    Jon Mazin
    April 26, 2013 - 11:04 pm | Permalink

    Thanks Umar for the good post.

    • 7
      Umar Ashfaq
      April 26, 2013 - 11:07 pm | Permalink

      Thanks for liking, Jon!

  • 8
    Fedor Tapochkin
    April 27, 2013 - 6:21 pm | Permalink

    Thank you for interesting article about Backbone fundamentals.

    • 9
      Umar Ashfaq
      April 27, 2013 - 6:25 pm | Permalink

      Thank you for comment, Fedor!

  • 10
    April 28, 2013 - 1:14 am | Permalink

    Hi,

    I think your post does a great job of explaining what I also found to be the most correct way of working with views and models.

    Regarding routers, my current approach is to have a model in the router instance which it is responsible for keeping updated. This router is instantiated by the top level view which binds to the model of the router.

    Thanks for the post!

    • 11
      Umar Ashfaq
      April 28, 2013 - 1:29 am | Permalink

      Thanks for sharing thoughts, Luís. Regarding routers, I tend to think that since they are the “first entry point” to your code which take control from the browser, they should be instantiating views and not the vice versa. But as I mentioned earlier, routers are yet bit hazy to me, so your approach might be better.

      • 12
        April 28, 2013 - 1:54 am | Permalink

        Well yes, I agree with that. My top level view represents all the application and inside it, given the router model state, different sub views will be instantiated.

        I’m basically using the top level view as what is in other frameworks the Application object. What kind of structure do you use to do thing kind of thing?

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    Wrap your code in [sourcecode language="java"][/sourcecode] tag (you can replace "java" with language you are using).