

Avoiding Common Backbone.js Pitfalls - liordegani
http://ozkatz.github.com/avoiding-common-backbonejs-pitfalls.html?tagref=js

======
jashkenas
Great article highlighting some common areas for attention -- _especially_
when first moving from vanilla jQuery to something like Backbone ... but
important for any basic Model/View layer separation.

For what it's worth, _all_ 5 of these points are addressed by the Backbone
docs, and there are some further nuances worth mentioning:

1\. listenTo() is great when you're connecting _from_ an object (frequently a
View) that will be removed long before the object that its observing is
removed. But when the two (the observer, and the observed) tend to live and
die together in the same cycles, no special care is needed, as garbage
collection will simply remove both together.

2\. An easier way to avoid multiple DOM reflows when rendering collections, is
to simply use a less granular template instead of a document fragment. You can
even render the "item" template directly within the optimized "collection"
template (remember, a template is just a function that takes data and returns
HTML). For example:

    
    
        <div class="books-collection">
          <% books.each(function(book) { %>
            <%= templates.bookItem({model: book}) %>
          <% }); %>
        </div>
    

3\. Absolutely. Addressed in the FAQ: <http://backbonejs.org/#FAQ-bootstrap>.
While bootstrapping models, be careful that you don't inject arbitrary user
JSON into the page without properly escaping it first -- if there's any data
shared publicly between different users of your app. Otherwise they can throw
a "</script>" into their post, and ruin your day.

4\. All of Backbone's "save" calls are optimistic _by default_. If you'd
rather a specific call be pessimistic instead, just pass "{wait: true}", in
order to wait for the server to respond with a 200 OK before emitting the
change on the client.

5\. Yep. Instead of putting further model changes in a "success" callback,
simply have a listener waiting for the "change" event. Then Ajax is out of the
equation, and whenever the model state is considered to be "change"'d on the
client-side, that change propagates appropriately through the system.

~~~
ozkatz
Thanks for the comments, valid points. regarding #2, it gets tricky when the
model subviews do more than just render the template (listen on model changes
and/or DOM events from their element).

Regarding #4, I totally agree. This is why I'm talking explicitly about the
"success" callback - it is often misused.

------
alexangelini
For those who have not yet tried it, I would highly recommend TIm Branyen's
Backbone.LayoutManager [1]. It solves items 1 and 2 very well.

[1] <https://github.com/tbranyen/backbone.layoutmanager>

~~~
rajivtiru
I've used Marionette up until now but this is very interesting. It looks like
this solves one problem really well, but marionette solves a bunch of other
problems with views/app management.

------
zaius
Respectfully disagree with point 3 - "Doing unnecessary XHR requests on page
load".

It's better to have your main app page completely static so it can be cached.
That said, don't use ajax either - load the initial data via its own script
tag.

~~~
SanderMak
Doesn't that also involve an extra HTTP call? I discussed the same issue as OP
a while ago: [http://branchandbound.net/blog/web/2012/11/unify-server-
side...](http://branchandbound.net/blog/web/2012/11/unify-server-side-client-
side-rendering-embedding-json)

Someone in the comments there mentioned a nice alternative to embeddding the
data in a <script> tag to avoid the problem jashkenas raised (</script> in the
JSON). Namely, setting it in a data- attribute.

------
ender7
Nitpick: I'm not sure that append() will trigger a reflow for every call. That
will only happen if you interleave calls to a reflow-required property such as
clientWidth. Anyone have a definitive answer?

------
dclowd9901
I often find people get hung up on the part where they already have an app
that isn't RESTful and doesn't necessarily return a clean JSON object on page
load.

Front loading data is an easy way around this and if you're savvy enough you
can create a fairly clean, agnostic shim to programmatically handle this for
you (so long as you can make your backbone info align with your backend model
structure).

------
rajivtiru
Does anyone know if marionette takes care of the DOM reflow problem?

I'm looking at the source and it looks like it does not.

[https://github.com/marionettejs/backbone.marionette/blob/mas...](https://github.com/marionettejs/backbone.marionette/blob/master/src/marionette.collectionview.js#L88-L94)

------
tocomment
Is backbone the best Javascript framework to go with these days? I'm keen to
switch to this style of web development but I'm waiting for the community to
pick a winner.

~~~
embwbam
I strongly recommend AngularJS. Huge reduction in application code complexity.
There are other good frameworks, like Ember, but the only one I wouldn't
recommend is backbone. The only things that it has going for it are that it is
easier to get started (but harder to continue), and that if you really love to
hand roll stuff you get to: both because it doesn't really do that much.

