This is an "almost-1.0" preview release -- so if you've got a Backbone app, I'd appreciate it if you'd take the time to upgrade, and report issues and concerns.
Some of the more significant updates are:
* `listenTo` and `stopListening` for easier event unbinding.
* HTTP PATCH support, for partial updates.
* collection.update(models) for "smart" add/remove/merge in one method.
* Events.once, a-la jQuery. Also jQuery-style event map syntax.
* Lots of performance tuning for triggering millions of events per second
(should you find the need) in modern browsers.
http://jsperf.com/events-vs-events2/3
Is that first bullet point a solution to view "garbage collection"? Or should those of us who want that sort of functionality continue to use extra helper code?
Somewhat. The usual rules of working in a garbage collected language still apply -- references are references, and keeping an event bound to another object is a reference to that object.
`listenTo` and `stopListening` just give you an inverted (and often easier) way to manage the references ... so that you can remove all of the references from the "other" side. For example:
view.listenTo(model, 'change', view.renderChange);
view.listenTo(collection, 'add', view.addItem);
view.listenTo(Backbone, 'initialLoad', view.reinit);
# ... and then, when you want to get rid of the view:
view.remove();
# Calls view.stopListening(), removing *all* of the
# events from "view" bound on all of those different objects.
Note that none of this is necessary if you throw away both sides of the bound event at the same time -- those will still be GC'd as usual. Also, this isn't just for Views. The methods are available on anything that mixes in Backbone.Events.
A comment on the description of listenTo on the Docs page:
> Tell an object to listen to a particular event on an other object. The advantage of using this form, intead of other.on(event, callback), is that listenTo allows the object to keep track of the events, and they can be removed all at once later on.
I had to read this a few times and the given example to see that the convenience comes from tracking events on the listening object side.
Using "object" and "other" for the object variable names makes it a little confusing. I didn't realize the bolded "object" meant the listener object, as opposed to the object being listened to.
Yes - view.remove() calls "stopListening" - so when you use "listenTo" all listeners should be taken care of.
This doesn't account for any child-views, or views that don't use .remove(), so you'll need to make sure those are taken care of when a view is destroyed. But in most cases, the garbage collection issues that have been seen relating to views & events are taken care of.
this probably isn't a bug, but just curious why the 2nd xhr parameter was removed from the collection parse handler?
I was using it to check the raw response and determine if the collection had actually changed & then supress unnecessary view renders. I worked around it by just stringifying the response instead, but it was a breaking change for some of my code.
Otherwise I've been playing around and it looks cool so far.
Because with the change that was made to parse more consistently ... i.e. whenever a "parse" function is defined, not just at the Ajax border, so that now if you have both `collection.parse` and `model.parse` defined, you'll get both -- parsing was no longer happening when an XHR object was necessarily available.
I'm also of the mind that it ought to be a function that works purely in terms of your data. For your particular use case (call collection.fetch(), and don't re-render if nothing has changed) -- give the new collection.fetch({update: true}) a try. That should give you zero events if all of the model contents are identical to what's already in the collection.
Will Backbone still send the whole representation of the object to the server when using PATCH? It's something that's always bugged me how I end up sending way too much stuff to the server.
Great release anyway the event handling is more than welcome and Backbone has been a joy to use for the past few months. Thank you for that.
This should make it easier to remove events from either end of a bound event -- either the side that emits the messages, or the side that listens to them, depending on what you need. For views (objects that tend to listen to many events from disparate sources), yes, it should make it easier. Be sure to use the `view.listenTo(model, ...)` syntax, and call `view.remove()` when you want to get rid of the view, and you should be all set.
In the doc:
- intead of other.on(event, callback), is that listenTo allows the object to keep track of the events, and they can be removed all at once later on.
typo "intead". ;)
Thanks for this great update. I like Backbone's Minimalist approach to structured JS programming.
Love CS even more.
Guys thanks for this amazing work... I am using it in my site and I am absolutely in love with this frame I am also evangelizing more Brazilians to use it :D
Will port my site to it right now.
The "event bus" and "listenTo" are very expected modifications I also liked the "Merge and Patch", I just got confused about the get using both CID and ID but I will take a look at the code later.
I can't figure why people at ThoughtWorks had put this beauty in the freezer, I would love to hear their reasons because that " abstraction pushed too far " doesn't do it for me.
I was at the Radar event in NYC this week and was thinking the same thing. If anything I always thought Backbone minimizes abstraction compared to most frameworks.
Funny, I only just finished refactoring our codebase (dozens of views, models, routers) using a 'custom' implementation of the listenTo mechanic, as well as a custom 'close' method for views that would deregister the events again:
I strongly recommend anyone starting SPA development to checkout AngularJS because I've found that its close to impossible to not end up with a mess when using Backbone.
I for one would never again use a library/framework just because its popular.
Really? I found Backbone incredibly easy to learn because it is so simple. Compared to most other attempts at JavaScript MVC frameworks, Backbone has a very small number of 'classes' and each class has a fairly small number of methods. The event system is incredibly simple and easy to grok. The backbone.js source is also very readable and if I'm confused about some implementation details I can easily locate the relevant source. In Backbone it's bad /style/ to continue using jQuery in an "old school" way (without using the helpers provided by Backbone.View) but it still works and this makes it easy to start porting jQuery-based code to Backbone.
Angular offers a different and more indirect set of abstractions, which means that (for me) it's harder to reason about what's going on, and it's not really feasible to look at the Angular source for clues. Angular feels like a good approach if you're willing to adopt it fully and follow its conventions, but this surely takes longer to learn fully than Backbone does.
Also, Backbone plays incredibly well with CoffeeScript, if you like that kind of thing (I do, but I understand that not everyone does).
FUD. I've had several developers over several teams pick up Backbone significantly faster than 1-2 months. I'd strongly recommend over generalising from personal experience, and perhaps considering why Backbone has so many devs using, and contributing to, it.
I've been writing MVC apps in JS and ECMA script in general (eg AS 3) for a good time now, and have used other MVCish frameworks before (Dojo, Flex etc). Backbone has a solid implementation of models, views and events. If you understand the fundamentals of Javascript (knowing event listener closures are references that'll prevent GC) and write modular code you can do great things with it without any "mess".
From reading the other comments here I get the impression it very much depends whether someone has used JS MVC frameworks before.
Having not tried any JS MVC framework before, I also have the problem of thinking backbone js doesn't seem to be so good as everybody is saying. Although I have to admit that I did not spend enough time yet. But from the examples (in particular the famous Todo example), I got the impression backbone js only works fine for apps with low complexity.
But who am I to judge, having it not used yet seriously...
In response to your last point: take a look at some of the real world examples that use Backbone (http://backbonejs.org/#examples) as compared to builtwith.angularjs.org. Real, huge projects like Hulu, Soundcloud, Moviepilot, and USA Today are all using Backbone incredibly successfully. Backbone doesn't provide a lot of the "plumbing" that other frameworks like Angular, Knockout, Batman, Spine, et al have built-in, but it's got a lot more resources and community that work much better for doing only what you actually need.
As a counterpoint, the first JS MVC I tried to use was Backbone.js, and it was really easy for me to learn, much easier than most others that I've tried.
I found Angular was easy to pickup - initially. Once you strayed from the path it became more difficult to understand. It is a cool framework, but I feel like you have to take it on whole-hog or nothing. Also - and this is completely and illogically subjective - it doesn't feel like JavaScript to me. It feels like Flex or I don't know what...
I built two apps with Knockout.js (similar to Angular I think) and many more with Backbone and I can say that it's true that it's harder to do non-standard things in Knockout than in Backbone (I'm talking about view layer). But there is a reason for this: standard things in Knockout are so much simpler and faster to do than in Backbone that it almost always pays off.
That being said, I see no problem at all with using them both at the same time. There is a Knockback project, which I found after I wrote a hundred lines of code helper that does exactly the same thing, and I can tell that the work great together. Backbone is good at the Model layer, it's Model ad Collection classes are very good; Knockout on the other hand is exceptionally good when it comes to Views and Controllers, almost entirely eliminating the latter.
I think that people fear the complexity of using both frameworks in one app, but in my experience it's not that bad. Everyone should give it a try.
They really do entirely different things. Angular allows you to create custom HTML tags, and have smart bits of HTML that react to arbitrary changes in a nested JSON object.
Backbone gives you tools for modeling the client-side data of your JavaScript application, and having an interface that reacts dynamically to those changes. In Backbone, the emphasis is on the data and rich models; in Angular, the emphasis is on the HTML structure.
Absolute nonsense. I was well into writing my first view helper extension for backbone at the end of the second week learning it, having already built a small app (comet shopping cart) in the first week.
There is literally a couple of days worth of reading to get up and running with either backbone or angular and the rest of the time is just standard write code -> question how good it is -> research better ways -> refactor loop that everyone should go through when picking up something new.
Seriously. I have been trying to figure it out or at least get started, and I can't ever get past "Hello from Ember.JS". At some point they will have some decent tutorials or something, but until then I have to pass. Just can't get my head around it.
I've used both Backbone and AngularJS, and found the AngularJS learning curve to be steeper than the Backbone one, and there's more 'jargon' to grok before you start understanding things.
How steep you find a learning curve is likely to be influenced by your technical history.
That said, the difference in difficulty, in my experience, is certainly not an order of magnitude.
I'm going to be trying angular, but backbone is popular for a reason.
My backbone code is very easy to understand, organized and not a mess at all. It doesn't need to be for everyone, but I think your recommendation may be misplaced.
Angular doesn't mesh well with progressive enhancement, and if I'm going to use an all-inclusive javascript framework, I'm going to go with the speed and intelligent architecture of Ember.js.
Some of the more significant updates are: