Hacker News new | past | comments | ask | show | jobs | submit login
Backbone.js 1.1 is out (backbonejs.org)
110 points by paradox1234 on Oct 11, 2013 | hide | past | favorite | 36 comments



For anyone who's looking for the changelog, it's at the bottom of the page so it's easy to miss.

* Made the return values of Collection's set, add, remove, and reset more useful. Instead of returning this, they now return the changed (added, removed or updated) model or list of models.

* Backbone Views no longer automatically attach options passed to the constructor as this.options, but you can do it yourself if you prefer.

* All "invalid" events now pass consistent arguments. First the model in question, then the error object, then options.

* You are no longer permitted to change the id of your model during parse. Use idAttribute instead.

* On the other hand, parse is now an excellent place to extract and vivify incoming nested JSON into associated submodels.

* Many tweaks, optimizations and bugfixes relating to Backbone 1.0, including URL overrides, mutation of options, bulk ordering, trailing slashes, edge-case listener leaks, nested model parsing...


I don't think I'm very picky about versions meanings. But still the first two items are huge breaking changes for a dot release...

If I hadn't left my previous job, It would take me a day or two to upgrade. Even Rails 3.2 => 4 is more straightforward.


How?

* Made the return values of Collection's set, add, remove, and reset more useful. Instead of returning this, they now return the changed (added, removed or updated) model or list of models.

Given that calling `collection.add(foo)` returned `collection`, when were you ever using the return value for anything? Going forward you might, but I would be very surprised if much if any code was broken by this.

* Backbone Views no longer automatically attach options passed to the constructor as this.options, but you can do it yourself if you prefer.

This might require going through your code base, but it's just adding one line in the `initialize` function:

    initialize: function(options) {
      this.options = options;
Annoying if you have hundreds of views that directly extend Backbone.View, but not something that should take a day to fix?

Am I missing something?


The return values change matters if you are chaining actions anywhere, which isn't that uncommon.

And yes, some people do have lots of views. In my current codebase we use Backbone.View as the base of all our frontend web components. This won't take us a day to update, but it's far from trivial, and we will have to regression test every component.


This should actually only take you 2 minutes if you'd like to keep the old behavior ... regardless of how many View classes you happen to have in your app. For example:

    var originalView = Backbone.View;
    Backbone.View = function(options) {
      var instance = new originalView(options);
      instance.options = options;
      return instance;
    };
Ahh..., isn't JavaScript just a lovely thing ;)


Sure you can hack things up like that. But when you use and update a library, you don't want to rely on deprecated behaviors.


Doh, completely whiffed on chaining. I can see that breaking in weird ways. Thanks for the insight.


> Am I missing something?

Well, I can't give you stats about the codebase anymore, but to give you an idea, the app was stated with Backbone 0.3, and contain between 2 and 3 hundred views, collections and models.

For the `.add` etc, it can seems straightforward, but when greping you will have a lot of noise from similar methods in other libs like jQuery.

The option is the real deal. Sure I can implement the behavior back. But I don't call that upgrading. If I upgrade I want my code to look like is was coded for the new version, not maintaining 3 years of hacks for backward compatibility.

So it mean that I have to grep hundreds and hundreds of `this.soptions.something` replace them by `this.something`and add `this.something = options.something`in the constructor.

It's a PITA.

And in fine I don't see the rationale for this removal, I failed to find the commit.



You're missing a lot, but you would have had to peruse the commits that have been happening over the past year to know how much has changed.

I'm not sure how to proceed with my own LayoutManager plugin. Hoping someone will PR a fix making it compatible, because my initial attempt told me it wasn't going to be trivial.


Looking into it, it seems like most of your issues stem from the fact that you depended on View._configure being called during initialization. You overwrite it here:

https://github.com/tbranyen/backbone.layoutmanager/blob/mast...

but this was completely removed with the update:

https://github.com/jashkenas/backbone/compare/1.0.0...1.1.0#...

In backbone's defense, that wasn't part of its public API, but it does make updating challenging. I'll give it a try and see if I can be of some help.


What are the issues you're seeing with LayoutManager? Are they reflected in the changelog or hidden in commit messages?


Yes, for that i prefer my own Namespace and extend not directly from Backbone (e.g. same when you use Backbone-Marionette).

Before you change your views, you should think about an own class on top of backbone and extend from that class.

So you can handle default behaviours easier and centralized.


I can't speak to the Backbone.js changes, but isn't one of the odd things about Rails versioning the fact that 3.x -> 4.0 is essentially a dot release upgrade, but 4.0 to 4.1 a full version upgrade (many things are deprecated from 3.x to 4.0, and 4.1 will remove them entirely?)


That was the plan, but now we are planning to make 4.1 an easy upgrade as well, and not remove deprecations that were originally planned on being removed.


Oh that's awesome. Thanks for the info.


That is precisely why our apps are currently "stuck" on 0.9.10. The upgrade process for backbone is rather painful, as you end up hunting for "undefined" issues all over the place.

Any change that renders my entire application broken should be a major version bump.


Here's a direct link to the actual net changes: https://github.com/jashkenas/backbone/compare/1.0.0...1.1.0#...


Where can I read more about changes related to nested model parsing and submodels? This is something I had to implement just a week ago, and I resorted to overriding `set`. I wonder if they made it easier, or if there is a builtin support for nested models of some kind.


Happy to oblige. There's no built-in convention for it, but you can do something like this:

    parse: function(attrs) {
      this.friends = new PeopleCollection(attrs.friends);
      delete attrs.friends;
      return attrs;
    }
... assuming that friends is an array of JSON objects suitable to be transformed into Person models.


Jeremy, thanks! I tried overriding Model's `parse` in 1.0 but wasn't satisfied because it seems to be called in some cases but not the others. (I can't recall a specific example right now; maybe it was parsing the collection from server, or creating a collection using constructor).

Do you think there are drawbacks to overriding `set`? It seems to work well for me but I'd love to hear your opinion:

https://gist.github.com/gaearon/6689379


If you want something lightweight I'd go with the approach @jashkenas mentioned. But also might want to checkout:

https://github.com/PaulUithol/Backbone-relational


Direct link to the changelog you quote: http://backbonejs.org/#changelog


How is Backbone faring against AngularJS these days ?


The opposing philosophies haven't changed - AngularJS really wants you to live in an AngularJS world and is a framework, whereas Backbone is more of a library and can be used to enhance your app (or parts of it) as well as providing structure.

Subjectively, they're both very popular although Angular seems to be growing faster while Backbone has been mature for a while.

If you're comparing them, remember it's apples and oranges - my company used Backbone recently in a mobile app and we loved the flexibility to use the parts that were helpful (Views, Events) without having any enforced application structure. It feels very light-weight but leaves much of the decisions up to the developer (there are frameworks like Marionette that provide more structure if you want it)

On the other hand Angular (or Ember for that matter) is great when you want to use it to drive your entire UI, and makes a lot of sophisticated behaviour easy to set up.

So I'd say they're very different solutions to client-side MV*, and not really competing. You'd use the one that suits your problem and how you want to build your app.


They try and solve the same problem with different levels of abstraction. I've gone full circle from Vanilla JS, to Backbone, to big monolithic frameworks like Ember and Angular and I've come back to Backbone. I think Backbone provides the right level of abstraction for the problems it solves. Angular and Ember I feel create their own problems.


Maybe it's just because I haven't gone full circle yet, but working with Ember I really feel I can focus on the domain issues and creating a great app.

With Backbone -- and the bunch of BB extensions (Marionette etc) you need to be productive with it -- I find myself just maintaining and extending massive amounts of boilerplate code.


Gee, that's an unexpected comment -- how refreshing.

As always, the best thing to do is browse through what's actually been done with them, compare the relative quality of the result, and judge for yourself...

http://backbonejs.org/#examples

http://builtwith.angularjs.org


Backbone is so much lighter than these frameworks, it really can't be compared directly. Angular is very popular lately, but you have to do your own research of the available choices and determine which project best fits your needs.


We were lucky to have jashkenas for a talk last week, and one of the questions he answered was how Backbone compares to Angular and Ember.

One of the key differences in philosophy with Angular is that Backbone tries to separate the UI representation from the core logic of your app by focusing on having rich models (alla MVC). Your models should have meaningful domain-related methods, and they should not know at all about the UI at all. Then have the UI observe those models.

In Angular, while it still draws a line between the UI and the rest of your app, there's not much focus on having rich model objects. However you want to represent your data is up to you, as long as you update the properties of $scope to have the views know about it.

Another key difference is the size of the feature set of each framework. While Backbone tries to give you the basic components for building a JS rich app and lets you decide how to solve no-so-basic things, Angular goes for a more full-featured approach.

An obvious example of this is view rendering. Angular provides templates with data-binding, filters, a way to abstract new "components" though directives and probably much more (disclaimer: i'm not an Angular user). In Backbone, on the other hand, the View#render method is empty, up to you to do whatever you want. You might simply use _.template and $.fn.html, or you can use some library to handle the data-binding (e.g. Rivets.js [1]).

This difference in feature coverage also reflects in the code size of the frameworks. You can totally read, and understand, Backbone's whole source code in an afternoon or probably less.

----

Personally, i'm not fond of the monolithic approach of Angular. In fact, i'd really love to see Backbone taking an even more minimalistic approach and decomposing its components even further: make the events, models&collections, REST handling, views and routing be separate libraries, and have "Backbone" be just a namespace with these things in it.

It's not that opting-out Backbone's specific features is difficult (it's actually very easy, as there's very little magic to what it does). But, for example, i don't think what Backbone provides for dealing with UI (basically, tracking of the DOM element associated with it and listening to DOM and model events... and a dependency of jQuery) is useful if you're going to use some library for data-binding. So, in that case, i'd prefer to opt-out and not even have Backbone.View lingering around. It'd be awesome to be able to do that by just removing a "backbone-views" dependency from the project.json file hehe.

Anyways, i think it's cool to have some healthy competition on this front of web development; there's still much to be polished.

[1]: http://rivetsjs.com/


I think http://chaplinjs.org/ provides a nice happy medium between the two approaches. It extends (does not fork) Backbone objects to solve those no-so-basic things for you. Yet it still keeps the UI as separated from the core logic of your app as much as vanilla Backbone.

Less tediousness than vanilla Backbone and a cleaner separation from UI and core logic than Angular.


Thank you for putting into words what I have failed to whenever someone asks me why I chose Backbone for our app development over Angular. The lighter wait library and MV* ness of it just made more sense over tying so much to the UI.


"angular or backbone: what are startups using" (blog post and poll)

https://blog.backlift.com/entry/front-end-frameworks


or ember.js?


No direct link to Change log. :(





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

Search: