But first, for the "kinds of things" that Backbone helps with, take a quick scroll through the list of examples available here: http://backbonejs.org/#examples
Here's a bit of typical (if exaggerated) jQuery to render/update the UI for a list of "accounts":
$(".account").each(function(){
var id = $(this).attr('data-id');
var data = window.accountJSON[id];
$(this).find(".name").text(data.name);
for (var i = 0, l = data.emails.length; i < l; i++) {
var e = data.emails[i];
$(this).append($("<div class='email'></div>").text(e));
}
var addresses = $(this).find(".address").length;
$(this).find(".address_count").text(addresses);
});
... note that we're looking into specific DOM classes, pulling data from a big 'ol global JSON object, looking up id values from the DOM, and so on.
Here's something a little bit closer you really want to write instead:
Accounts.each(function(account) {
new AccountView({model: account});
});
For each account, render its UI. Of course, this is just sweeping a lot of the complexity of the original example under the rug -- but that's the point -- you want your UI in HTML templates, and your data/model logic to be in "clean" JavaScript code unpolluted by UI concerns. Then, when you refactor your design later, all of your client-side business logic doesn't have to change -- it no longer cares about global nested JSON structures or concrete DOM elements.
For another Backbone example, imagine taking all of the songs by a given artist, and rating them with 5 stars:
I have to admit that whenever I see “MVC something” a lazy instinct kicks in. Probably because it seems like an overkill and I know I can code something in a few minutes (which is never true) that will do the same without having to learn it.
Usually, learning is most fun for me when I have a problem to solve or when I get really curious about something.
And that song example falls in the second category.
I had the same question after trying to use Backbone on a couple different small projects and giving up after seeing it introduce more complexity that I saw it removing.
Recently, I discovered Knockout.js, which is a "competitor" to Backbone with what I think is a clearer interface and a much clearer value proposition. I've had a lot of success with Knockout and fully expect that, like Sinatra did to me with Rails, Knockout will teach me to appreciate Backbone soonish. In the meantime, here's the knockout pitch:
What Knockout does is allow you to keep separate models (which are plain-old Javascript objects; Knockout doesn't need to infect them or enforce any kind of structure to them at all) and DOM UI. Knockout's job is to keep the two in sync. For instance, if you have an array of Foo's rendered in a table, Knockout allows you to bind a "foreach" to the table's body, effectively turning a single TR into a template for each Foo. Then, if the elements of the Foo array change dynamically, Knockout makes the table reliably reflect the constitution of the array.
The core value here isn't "templating". It's "keeping the DOM in sync with Javascript objects".
Off the top of my head, I think we're talking about 3 lines of code to get that functionality: the data-bind attribute on the TBODY element, the ko.observableArray() that wraps your otherwise plain array of Foos, and the ko.applyBindings(RootModel, RootDomElement) call that kicks off Knockout.
The same functionality would probably cost 10-20 lines of jQuery; more importantly, that jQ code would be fiddley, not at all declarative, and duplicated every place you wanted to bind an array to some repeating DOM structure. Knockout is here, to my eyes, a clean win.
Or take forms: you bind (with data attributes) INPUT elements to Javascript objects, so that what their values are changed by user input, the Javascript objects automatically reflect their new values. The JS code that then cares about the value of these objects doesn't ever need to scrape out the values of forms, and can reliably assume whatever's in the fields or hashes or whatever you set up is going to be current input. Also: you can bind multiple form inputs to the same data and keep them in sync, which I found to be a pleasant way to implement an "Advanced Search" feature.
What I didn't like about Backbone was the notion it had of "Models" and "Routers" and stuff like that. I'm sure that's valuable structure to have, but I like the flexibility --- and, more importantly, the freedom for More Stuff I Have To Memorize --- that comes with the KO.js approach.
Recently I discovered AngularJS (http://angularjs.org) by some of the guys at Google. I spend most of my time on the backend and have never been a fan of JavaScript, but the AngularJS declarative design really caught my eye. It's so clean and so simple. I think it's brilliant.
A colleague and I are using it, and it's been great thus far. The learning curve is a bit steeper than other similar frameworks, but once you get the hang of it, development is very quick. The Angular guys are very helpful as well.
I'm using it on a project right now. It's my first project with it, but so far so good. The tutorial is quick and straightforward, and it really gives you a flavor for it (http://docs.angularjs.org/tutorial/).
AngularJS is a lot like Knockout, without the ko.observables everywhere.
I've been using Angular in a few prototypes and ran across funky problems using their routing in HTML5 mode with IE9.
Theoretically their router should prepend the hash fragment to the URL, but it gets stuck in a redirect loop and hangs the browser. The workarounds I've found so far are to use hash style URLs or not use a default route, neither of which are optimal. (Edit: updating to 1.0.1 fixes the problem as long as your "otherwise" route is a defined route)
Version 1.0 (they are currently on 1.0.1) of the framework broke their website for IE users, which makes me a little nervous about the level of cross-browser testing that the framework uses. Their documentation is sparse in some areas, which is an annoyance more than anything (the source is fine to read, but be forewarned that it's not a small project by any stretch of the imagination).
On the plus side, not having to litter ko.observable everywhere was nice, their concept of services (for working with REST endpoints) is great, and it's been pretty easy to break everything up into maintainable modules.
Neat. I don't love the ko.observables, but as an alternative to having to have objects fit into a predefined structure/class hierarchy, they seemed like a good tradeoff.
I used Knockout.js on a project before switching over to Backbone.
My experience was that while Knockout is great for simple projects, it becomes a lot more complex than Backbone once things get complicated.
All those data-binds in the HTML get really annoying and the application becomes difficult to maintain. I like my templates clean.
Backbone takes care of syncing your data with the server, provides you with an event system so you can subscribe to changes, gives you a sane convention for how to structure your views and then gets out of your way.
It's also easy to extend, so you could write your own data-binding system if you really need it. A simple 1-way data-bind is quite easy to implement.
If you aren't writing a single page app and only need to make a primarily static page more interactive, Knockout is probably the right choice.
If you are writing a single page app, you often need to sync your models and collections with the server, or if your UI is very complex, Backbone is probably better.
I believe you, but would just say that for me, syncing data between the browser and the server is pretty easy; it's syncing data to the DOM that's challenging. I totally believe Backbone is great that that, but it makes design tradeoffs for syncing to the server too, and I just found no benefit from that.
Anyways, I think we're saying the same thing. The question: how is Backbone better than jQ; many answers; Ko.js as a middle ground.
I want to echo this last remark. We often need to sync with the server and our UI can get to be relatively complex. Backbone is an outstanding tool for us. However, we don't have single page apps (yet) and we've removed any routers from our apps since they were unnecessary.
I believe many of the references on the web regarding Backbone (blogs, tutorials, stackoverflow) actually confuse matters and made my team's learning curve steeper than it needed to be. Also, the Backbone documentation isn't particularly newbie friendly. I strongly advise anyone first looking into Backbone to ignore Routers completely until the relationship between Models and Views is understood, and you've deciphered the patterns that express that relationship.
We also use Coffeescript, which increased the trouble of learning Backbone. But it was well worth the extra head scratching.
I've had a similar feeling, and have been experimenting with a little library that's fairly similar to Knockout(which is awesome), but is smaller and enforces what I think is a cleaner binding syntax.
>I've had a lot of success with Knockout and fully expect that, like Sinatra did to me with Rails, Knockout will teach me to appreciate Backbone soonish.
Someone asked me to describe the difference between backbone and knockout the other day - and I said "knockout is to backbone what sinatra is to rails" - if focuses on one tiny part of the problem and leaves you to sort the rest however you want.
I'm not sure it lends itself to such contrived examples. A more useful comparison would be the use of backbone to build an entire web app (a small one). Backbone has a number of components and it's not exactly like you can have a three-line diff of the two to explicate the merits of one of the other.
Check out the Backbone one and the jQuery one. They should basically be the same idea, suited to each of the two frameworks.
Also, remember that Backbone and jQuery are not mutually exclusive (quite the contrary -- Backbone actually requires jQuery/Zepto). So you're sort of comparing Tangerines and Oranges.
The problem Backbone.js solves is primarily that of structure and organization. It's not about replacing jQuery, its about how you organize that code and have a clearer separation of interface, data, and logic.
The Backbone implementation is an adaptation of this: http://backbonejs.org/docs/todos.html which i think is more readable. The todomvc adaptation is a little over-structured for my taste, too many JS files for too little functionality.
IMO it's not so much that frameworks need to solve these things, it's that you should be wrapping this sort of functionality in a more declarative way regardless, some devs either don't think about this at all or let it get out of control. I fully agree with Jeremy that you should not be using jQuery directly, I can't think of any case where it could not, or should not be abstracted out, jQuery is just the DOM helper. I like bits of backbone but I wish they were decoupled so you could just take the bits you wanted
Here's my iconoclast answer (with a further caveat that I'm a systems programmer who follows web development in my spare time, not an expert on any of this):
Backbone (or Spine, which is just like Backbone but a tiny bit smaller and written in CoffeeScript) is Yet Another MVC Framework. So think of it like Rails, except this time it runs in the client browser. So instead of translating between SQL and Ruby, you're translating between JSON and DOM. There's a "Model" abstraction, which is just a data structure but has fancy features like the ability to "save" it to the server and the ability to listen for changes. And there are "views", which are just the same old DOM/CSS/jQuery environment you know, with the single stipulation that they need to be associated with exactly one Model. And, just like rails, there are "Controllers" which all the guru's seem to understand just fine but that look like huge messy piles of logic soup to the rest of us.
And, like all MVC frameworks before and after, it's subject to the framework disease. You don't "use" MVC, you "port to it". It infects everything you do, such that you get indoctrinated into the particular MVC subculture you've chosen and spend your time screaming at other people on the internet instead of writing code (edit: c.f. rimantas below.).
Stay away. Or if you must use it, be sane and safe, and stay away from the culture.
Yep, stay away from the advice of some systems programmer who "follows" web development and feels entitled to comment on thing he knows very little about.
Backbone is not MVC framework, it does not have Controllers. The name is very apt: it is basically a small skeleton for your app which gives you things you'd have to reinvent and provides some organization and structure.
Actually, the description on backbonejs.org describes it very well:
> Backbone.js gives structure to web applications by providing models with
> key-value binding and custom events, collections with a rich API of enumerable
> functions, views with declarative event handling, and connects it all to your
> existing API over a RESTful JSON interface.
It is very small and simple (and even "rich API of enumerable functions" is provided by underscore.js on which backbone.js depends).
Backbone doesn't actually have controllers, only models and views. Even without that technical distinction, I'd still be hard-pressed to actively describe Backbone as MVC (especially compared to other JS frameworks like SproutCore or Ember, which do actively force you into a more traditional MVC structure).
It doesn't actively encourage you to structure your code in any particular way, other than "separate your business logic and DOM logic", which you probably want to be doing anyway if you're building the sort of JS-heavy rich web application that people tend to recommend Backbone for.
* One is just a fancy web page, it uses Backbone in a traditional sort of MVC way. I don't use the router tho, doing my own thing with pushState and gradual enhancement. Lots of views and models keep things separated sanely.
* Another uses it because I wanted an easy mechanism to map between storage and app. I think the only reason I used views in this case was because I had already been using a template, so I just threw it in a view to tie events together.
* The last I don't use any of the "talk to the server" features, but use the event model because it allowed for easier reactive style stuff with events and forms, and tying into canvas frameworks than alternatives. The data model doesn't fit nicely with Backbone, so I did my own thing.
The point is, Backbone keeps it easy to not get sucked into the whole model if you don't want to.
This is complete rubbish. Backbone doesn't care about the DOM, it works nicely with jQuery, but it helps you to remove app logical state from the DOM. A view can bind to as many models as it needs, it simply has a connivence helper for a single model called "model".
Backbone doesn't care about the DOM in precisely the same way that Rails doesn't care about HTML. And Model isn't a "convenience helper", it's a class from which you must inherit if you're going to do anything at all. A "helper" for this stuff would be something like a "save" function that took an arbitrary Javascript object and pushed it automatically to the right CRUD method on a server. Backbone isn't like that at all. Dependencies like that fester.
You said a view can only have one model, I was saying that within a view "model" is just a connivence helper function, you can reference as many models as you like, but give them their own name
You certainly have strong opinions for someone with no idea what they're talking about. Here[1] is the official backbone documentation. Please, point out the "Controller" objects.
While you're looking for that, maybe you should consider leaving the explanation of a technology to people who have taken the time to learn something about it.
You should try Backbone.js. While I do appreciate your general sentiment about the cultures, you should try it first. It's not really as big a deal as you're making it out to be. It's actually pretty small and doesn't do that much. You can make views using lightweight templates or not, your choice.
The main issue in my view is that most of the examples out there are just too simplistic. But it's too light to be considered an indoctrination platform like Rails or something like that.
If you want to see a large production app built in backbone simply fire up Firefox and go to: http://www.documentcloud.org/public/search/?debug_assets=tru... and save the source code and read through it. The debug_assets flag will return the entire unminified code.
jashkenas went over a lot of this in the State of the Backbone at Backboneconf. Regretfully you can't see all of the examples in the video... but you can hear his description here:
Not a description like “it will replace a lot of your jQuery spaghetti boilerplate”, but some actual code: