We at Quick Left have done battle against the likes of spaghetti DOM code and phantom views, and lived to tell the tale. Here's a new nugget from our adventures: Idempotent View Rendering
First, let's get the ten cent word out of the way: Idempotent means, for our purposes, that you can call a method many times, and the results don't "stack". You can call it multiple times and it will always have the same result, e.g. there are no additional effects from calling it multiple times.
Very often when writing a Backbone.js view, you'll implement the render code like this:
This is a great first pass, as it gets the content onto the page. It falls apart when you add re-rendering events to your view though:
The view will re-render when its model is changed, which is a Good Thing. The view reflecting the current state of the data is desired, but what's not is the buildup of DOM cruft you'll quickly see. Each change event will put an entire new instance of the
el at the bottom of the
#content element, and each new
el on the page will have n+1 instances of its content, because it wasn't emptied properly. If you changed the model's
name property from 'Alex' to 'Al', it might look like this:
That's not ideal, so we'll do a quick refactor to make sure that the adding of the
el happens just once in initialize. The second key is to use
.html() instead of
.append() to make sure that subsequent renders don't stack up INSIDE the
el. Check this out:
For a scenario where you might want to update differently based on the attribute being changed, here is another great approach:
.render() as a one-time-only method, it frees you up to write methods that apply different effects based on the attribute being changed, like so:
The thing we like best about Backbone.js at Quick Left is that it lets you write different code for different scenarios, and this is a great example of not being hemmed in by a particular framework's approach to rendering. Awesome!
How do you handle re-rendering your views?