

Rendering Views in Backbone.js isn't Always Simple - calvinfo
http://ianstormtaylor.com/rendering-views-in-backbonejs-isnt-always-simple/

======
jashkenas
This approach seems like a reasonable way to go ... but you also seem to be
doing a bit more rendering than you really need to. If I understand the
premise correctly, you have a situation like this:

    
    
        +------------------------------------+
        |                                    |
        | MainView                           |
        |                                    |
        | (content)                          |
        |                                    |
        |                                    |
        |+----------++-----------++---------+|
        ||          ||           ||         ||
        ||SubView   ||SubView    ||SubView  ||
        ||          ||           ||         ||
        ||          ||           ||         ||
        ||          ||           ||         ||
        ||          ||           ||         ||
        ||          ||           ||         ||
        ||          ||           ||         ||
        |+----------++-----------++---------+|
        +------------------------------------+
    

... and the data for the MainView is changing, while the data for the SubViews
is not.

So ideally, just re-render the top part of the MainView, and leave the
SubViews alone. Instead of trying to reuse the same "render" function, imagine
doing this instead:

    
    
        mainModel.on("change", mainView.renderMainContent);
    

... where the hypothetical "renderMainContent" function just renders the
template for the top half of the box. Or, maybe the top half of the box is a
sub-view in its own right that can listen to its own events. Or, maybe you
don't even need a template, and you can just update a couple of granular
fields and/or attributes with jQuery. Whatever works.

~~~
tristan_juricek
Yep, I was wondering why "render" would need to be called multiple times.

I usually start off by doing that because I'm lazy, then something usually
bites me in the ass (usually - oh hey, we need a transition effect).

And the end result is a bunch of "sub rendering" methods that get called in
render ... and as callbacks from model change events. (It's awfully nice when
you have to load everything off the server - no default state in the DOM.)

~~~
ianstormtaylor
I completely agree with the small render helpers, we've been using that too
and it works amazingly. I'll probably write about that next. But I still want
`render` to be able to be called multiple times without breaking because it's
a public method.

I'd love to read an article about how you guys handle transitions though.
We've implemented a few of them, but I have yet to work on them enough to have
found really nice patterns.

------
FuzzyDunlop
I'm not sure why there's so much significance attached to `render()`
considering that it's a no-op in Backbone, and you've got an entire class to
work with.

Trying to figure out how to cram everything into one function while still
getting desired behaviour doesn't seem like the best way to go.

That being said, there are probably better ways to do it that don't involve
Backbone, too.

------
brunoc
Backbone.Marionette is a nice set of view classes (and a few other things)
solving a lot of the typical use cases for Backbone in medium to large
application. Amongst other things it provides a Layout view with a simple
region manager to take care of 'full page' or large views with sub views.

<https://github.com/derickbailey/backbone.marionette>

------
drdaeman
Does more rendering than necessary and is still not perfect, as it won't
preserve DOM state on model state changes. For example, consider <details>
state (rolled up or not) - setElement won't keep it.

IHMO, somehow better (but more verbose) approach is to consider view as a FSM.
Each state may render view's complete representation (using the template),
while each transform (an edge of view's Moore machine) may transform DOM tree
as necessary (i.e. just update necessary elements instead of re-rendering a
whole subtree, if possible).

I belive, this could be automated (as DOM is, essentially, a tree, differences
between states could be found algorithmically), but haven't really tried it
that way.

------
jakejake
I took the approach of making a class called a "ModelView" which adds a few
things - one of which is an "On Render" event that fires after the view
renders. we do all of our jquery binding in our onrender function and so
whenever the view re-draws, onrender is fired and all of the jquery stuff will
be re-bound.

It would be nice to have the view re-drawn more intelligently so things don't
need to be re-drawn and re-bound each time. But, I couldn't think of a generic
way to do that without knowing the details of the view.

If anybody has any interest, the code I wrote is at <http://phreeze.com>

------
ernestipark
Nice article, Ian! Just starting to lick my chops with Backbone and these are
some of the questions I'm dealing with. Would love to see more articles.

------
DonnyV
B L A C K M A G I C! ...and that is why I stay away from any of these MVC
frameworks.

~~~
hogu
backbone has very little magic in it - and the particular confusing aspect
mentioned in this post has to do with ubinding events by calling .html, which
has nothing to do with backbone, that's all jquery.

