Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Break Apart Your Backbone.js Render Methods (ianstormtaylor.com)
87 points by ianstormtaylor on Aug 28, 2012 | hide | past | favorite | 17 comments


Another great article, Ian. As a newbie to Backbone, I find myself refactoring and going over best practices frequently. One of the first things I found myself trying to wrap my head around is different ways to render my templates properly. This seems like a good approach when you have pretty distinct modular chunks that are reusable.

Rivets does look promising in that there are some parts of my code in templates that are just a single number (say # of notifications). That's a pain to have to separate out into a separate view or render function for something so small.


> I find myself refactoring and going over best practices frequently.

I'm curious, what kind of changes have you adopted to as a result?


This is not a problem specific to backbone rendering. This is a common issue in jQuery plugins, and vanilla javascript in general. Its a best practice overall to keep your functions small.

Have them do one thing and do it well, keep them unix like, small sharp tools. You can always copy paste a large conditional from one function into its own named function. This significantly improves readability and divides the code in to smaller units which makes testing more graceful.


What made you choose this setup over subviews (with one render per subview)?


It's just a question of how many subviews you want to make. In this case, I don't really think the label itself needs to be a subview since its such a simple component. The only action I associate with labels is for clicking them to focus their associated input. Which wouldn't even be pulled into a LabelView, so there's really nothing to it, so I don't gain much from separating it into its own view.

You can probably argue both ways though, I used to have labels be their own view actually. It just got a bit more uselessly complicated for so little benefit.

If the view you're dealing with is an end node in the view hierarchy (and it's pieces are relatively simple) then I prefer not to split them up because there are costs there as well.


This is the problem I run into every app I make...when I try subviews I usually end up giving up out of annoyance at the complexity


Dunno if it will help, but I wrote earlier about how I handle rendering subviews: http://ianstormtaylor.com/rendering-views-in-backbonejs-isnt...


the problem the author is solving is clear; "Instead of writing gigantic render functions that do everything under the sun (and then more, admit it!) you should break your render methods into small chunks. That way you only ever re-render what you need."

but breaking apart your render method is only one way to achieve this. using a sane layout manager with subviews is my preferred approach (though i suppose you could argue this is just breaking up the render method across several views). this technique is also admittedly a pain at small scales.

the beauty of this technique, though, is that every view is responsible for it's own rendering. that is, parent views don't need to be aware of the re-rendering process of their subviews (how or when). another great benefit is you will find yourself referencing items by selector less often, and instead through the subview's element.


I do structure my code in a similar way. All the elements in a view, that have to deal with data, are treated as a separate view module. Each module will have it's own view, template, model and style.

The template for the main view, or the subview that can hold modules,is structured in such a way to have a .container to append my modules into.

The main view is usually rendered only once and behave as a proxy for the various modules relying to the events.

The great benefit form this approach is that it's quite easy to maintain/replace a single module as long as the events api don't change.


awesome, yep. sounds nearly identical to my tactic; with 2 minor exceptions. first being i don't necessarily have a unique model for each view- lots of times my subviews use the same model as the parent or sibling views.

second is i actually define the sub views element from the parent view on instantiation, and operate under the assumption that all subviews will render by emptying their element and replacing it's contents. the primary reason is so the root subview element never changes (which can lead to complexity).


Same here for subview rendering.

About the models I prefer to use an unique one for maintenance and team development cause it's harder to accidentally break things.


Completely agree. http://ianstormtaylor.com/rendering-views-in-backbonejs-isnt...

It's just a question of how small you really want subviews to get. I personally don't think it's beneficial to have a single label be its own view. Especially when you could have many many inputs on a page.


Doesn't this necessitate lots of individual templates? (in this example: inputTemplate, labelTemplate...)

Is there an easy way to manage this? From what I've seen it's typical to have one template per view (and possibly sub-views with sub-templates).


Dunno about easy, but we use Require.js with either the text! plugin or a custom plugin for jade templates, so they're in their own files.



May I suggest more line breaks, and fewer inline if statements. The two would make your code more readable.


Maybe. I've actually adopted the style from Backbone itself. https://github.com/documentcloud/backbone/blob/master/backbo... I've found that while it make individual methods harder to read, maybe, it helps with readability of the file in general. If your methods stay small and are well named, you don't need to read their internals as often, but scanning the file quickly, it's much easier to get a big picture.

I used to be very liberal with line breaks, but then seeing methods as their own blocks gets harder. It's just a trade-off. Those example methods could probably use a single line break each, I'll give ya that :p




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

Search: