Hacker News new | past | comments | ask | show | jobs | submit login
Hello Backbone.js - A step-by-step tutorial (arturadib.github.com)
245 points by arturadib on June 7, 2011 | hide | past | favorite | 47 comments



This is exactly what it feels like to build Backbone interfaces!

Definitely would give someone a leg up learning for the first time, compared to the Todos app. Plus it doesn't have anti-patterns like `this.model.view = this`, a line which Yehuda Katz actually mocked at a recent SproutCore meetup.


Out of curiosity, what did Mr. Katz say about setting a reference from the model to the view at the meetup?


He had led in to a section on "Other MVC Frameworks". Then a single slide with some code along these lines:

  Todo = OtherMVC.Model.extend({
    clear: function() { this.view.remove(); }
  });

  TodoView = OtherMVC.View.extend({
    initialize: function() { this.model.view = this; }
  });
Basically he ragged on that for breaking MVC, and never mentioned Backbone by name. I spoke to him afterwards, and he seemed pretty set against Backbone. He considers manually bubbling events to be tedious: "not the happy path".

I've been inspired by Morphic recently, where models having knowledge of their views makes sense. When I was a beginner though, I was briefly puzzled by how to connect multiple views to a model and vice versa: I first tried to extend the pattern above before binding to model events.


I thought loose coupling was a feature.


lol! I saw the same at another recent meetup. Damn, Katz really doesn't like Backbone...


As someone who's just getting started with Backbone, I'd be very interested to see that talk, and here suggestions for what to do instead of 'this.model.view = this'.


If Spine is anything to go by, you bind events from the view to the model and then trigger them from your code on the model instance.


Usually that's the case -- but if you know for certain that there's a one-to-one relationship between a model and it's view, then there's no harm in having a direct reference for convenience. Pragmatism > Purity, where UI code is concerned.


I agree with you. I'm concerned about memory leaks from the circular references, though.


Circular references are garbage collected -- no need to worry about them.

You might be thinking of a terrible old IE bug where circular references between JavaScript objects and DOM nodes were never collected, but that's never been an issue with JavaScript-only references.


Oh, I didn't know that. That alleviates many of my concerns, then, thank you.


The Responder pattern used in SproutCore (inspired by Cocoa) is very elegant.


This is my first exposure to Backbone (aside from hearing DHH recommend it at RailsConf). It looks like it helps formalize a lot of what I'd already come to realize was a good way of doing large JS apps - MVC design.

However, I've found one of the most painful things I have to do when doing a lot of JS is dealing with HTML as a string. Escaping quotes is a pain in the neck, syntax highlighting is broken in my editors. The HTML here is pretty simple so it's not problematic, but sometimes you need to render larger, more complex blocks of HTML. HTML is just not as easy to work with in JS when you compare it to the templating systems provided by Rails, Pylons, etc. Does Backbone have anything to help this?


Not Backbone itself, but its dependency written by the same (awesome) developers: Underscore.js. Underscore has functions to help you with client-side templating. It basically boils down to you writing html as you normally would within a script tag, like so:

    <script id="foobar" type="text/html">
        <ul>
            <li><%= test %></li>
        </ul>
    </script>
Because it's in a script tag, the browser doesn't render that snippet of a template on its own. And since the type is text/html, the browser also doesn't try to interpret that as javascript. Now all you have to do is select the id of the script tag using your favorite library (like jQuery) or with getElementById, get the innerHtml as a string, and pass it to Underscore's template function along with a dictionary of values that you want replaced (such as test above). Like Django or Rails templates, you also can do some basic logic within the template, like looping over an array to make a list of items.

If Underscore's syntax isn't your cup of tea, there's a slew of other libraries available, like Mustache or jQuery's own tmpl module. You'll never go back to building the DOM yourself or dozens of concatenated strings of html again!


I have a class called Tag with static methods for all relevant tag names which merely wraps $('<' + tagname + '/>') and thus allow for stuff like:

   Tag.ul(
       Tag.li('unclickable li tag')
           .addClass('unclickable'),
       Tag.li('test clickable li tag')
           .addClass('clickable')
           .click(function() {
               alert('clicked on test')}))
I prefer this as it keeps my view code "in language" and makes it easy to apply any sort of jquery methods which I need to the different elements.


Backbone itself doesn't have template support, but there are loads of libraries for that. There is a list in this performance rundown:

http://jsperf.com/dom-vs-innerhtml-based-templating/160

Another path is "anti templates" like http://beebole.com/pure/ or https://github.com/hij1nx/weld


Yes, embedding HTML in strings is an awful pattern, and something you should strive to avoid at all costs. Backbone.js is intended to work with the templating library of your choosing, and there are good JS templating helpers for Rails in the form of Sprockets 2 and Jammit.


Yeah but if you look at the structure of this, it's just using jQuery's abilities to append stuff. You could just as easily build a node structure using document.createElement and append an actual DOM node to the body, if you're concerned about mistyping raw HTML.


What about jQuery?

$('<div>', { class: 'content', id: pageId })


That's fine for a simple DOM element, but quickly gets out of control. Imagine a list rendered in a loop from a JSON array.


Feedback and contributions are always welcome. Feel free to fork it and send pull requests.


very nice. I'd like to see some use of underscore templates to replace some of the jQuery append/html rendering techniques. Also, routing would be cool.

(nitpik: In your swap method there is a variable swaped, should prob instead be swapped)


Doh! Thanks, swapped now fixed :)


Very cool work. Would have been great to read when I was starting out with Backbone.

One question: there's only 5 steps created thus far, correct?


Hey thanks. Yep, so far only 5. What would you suggest to come next, persistence? Routing/controller?


Persistence please


Don't forget about spine.js: http://maccman.github.com/spine/

It's essentially a fixed version of Backbone. It gets rid of the psuedo getters (you can do model.attribute instead of model.{set|get}('attribute')). It gets rid of "collections", and just adds them as class methods on the model.

It just makes more sense. It's getting a bigger following, and I hope it can reach the mass of backbone someday.


I wouldn't call it a "fixed" version of Backbone. It changes some things I'm not overly concerned about (getters) and replaces collections with something that at first glance appears less useful.

I like collections, they give me a good place to put any logic and state involved with groups of models. If need be I can have multiple collections dealing with the same model class, each with whatever varied behavior needs supporting. In spine it looks like I get to manage all of that myself, which appears to be a trade of versatility for simplicity.

Not trying to knock Spine, I just don't like it when "oh it's a fixed X" is used to mean "it's a version of X that does things the way I like". There are a lot of actually broken projects out there, Backbone is not one of them.


Yes, I would say that if want to emulate what you're doing with Collections in Spine, it's just a case of subclassing the model. This makes more sense imho, and may lead to even further code re-use.


@awj has this right. I very much appreciate projects like Spine and wish it great success, but it's an alternative, not a fixed version of the same thing.

Pseudo-setters exist in Backbone for a very good reason: change events, and Collections are (IMO) more than 50% of the entire usefulness of Backbone in the first place. The point is that you have solid aggregation and analysis functions to base your model manipulations on: map, reduce, filter, find, every, some, etc etc.


Good job arturadib... Most programmers(or rather lesser programmer like me) tend to walk away from teaching once they had grasped the new lanaguage.. I managed to struggled through Backbone for the last few days and I'm beginning to see the light of it.. Will try to come up with a tutorial if I find the time!


This tutorial fails one of the basic tests of a good introduction as put forth by the recent article in Dr Dobb's (http://news.ycombinator.com/item?id=2607303): it provides no motivation. What is Backbone.js good for? A basic tutorial might want to explain _why_ I should take the time to engage with it.


Hey thanks for the constructive feedback.

The Backbone project page already does a good job of describing the motivation behind it.

From the front-page of the tutorial: "[This tutorial] was designed to provide a smoother transition from zero to the popular Todos example [provided in the Backbone website]."

Also, it's on Github for free - contributions are welcome!


My guess is that I'm close very close to your ideal intended reader. I'm a javascript programmer looking for better ways to handle and persist state in my apps.

I think you might be dismissing the above criticism too quickly. Arriving at the page there wasn't much that told me what problems Backbone would solve or what features it offered. It was also rather difficult to actually get to a working version of the Todos demo (it's not linked from the annotated source or the step by step tutorial, as far as I can tell).

In the same way that there's a bolded summary of the idea being expressed at the start of each page of the tutorial, I think a similar summary of Backbone at the beginning of the tutorial would be helpful.


Yep, fixed (Todos link), and fixed (Backbone explanation)! :)


I went to the project home page and found the first paragraph in the intro section to be the most concise statement of the problem Backbone.js is trying to solve, but even that states the case for the project's existence in negative terms: it helps you avoid a problem. But that problem comes up when you're trying to accomplish something, and it would be better to say that Backbone.js is an awesome way to insert MVC stuff here.


OK, fixed. (Refresh the main page to see changes).


Awesome tutorial. I have been experimenting with Backbone for a few weeks now. I did not understand the point of _.bindAll(this, ..) in initialize till now :)

It would help if the sections of code that you add in each step were highlighted somehow. I definitely like the step-by-step approach.


I built http://www.facebook.com/nikerunning?sk=app_151033471623290 with Backbone.js. Still trying to get my head around underscore and controllers.


Cool thanks. I'm not sure docco, the document generator I'm using, allows that type of highlighting. (anyone?)

But to some extent the comments on the left already point out new sections of code - only new material gets those comments.


Do we really need to get all methods with 'this' bindAll'ed? I'm using it only for methods who get callbacked.


Nice tutorial!

I see few people asking about templates with backbone. I have been there few days back and have ported the TODO app to run on Rails 3.1 with view templates (using coffeescript ofcourse!)

https://github.com/sujithrs/todo

Enjoy!


There is a shortcut for finding items in current view: "$('ul', this.el)" - this.$('ul')


This is a nice tutorial, thanks @arturadib. btw, backbone.js has an unofficial google group at: http://groups.google.com/group/backbonejs


I had made plans to learn backbone.js today. I checked out HN this morning and voila there's a fresh tutorial posted :) Thanks so much!


I'm learning Javascript and wish there are some Javascript tutorials like this somewhere :(


I don't even know whats happening.

http://backbonetutorials.com




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: