Hot on the heels of my Backbone.ModelBinding plugin release, I pushed a significant update out to the github repository. Included in this release is the rest of the form input types, including radio button groups, select boxes, etc (be sure to read the documentation in the readme for a more complete list of Backbone.ModelBinding supports now). More importantly, though, in order to get the rest of the form element conventions built, I had to create a pluggable architecture for my plugin.
That’s right, folks, my plugin allows plugins. :)
And with the ability to plug your own model binding conventions into Backbone.ModelBinding, I had the crazy idea of putting together some basic ‘data-bind’ attribute binding for any and all html elements and attributes, ala Knockout.
Re-Rendering On Model Update
Let’s take a look at the example I keep using for this plugin, again:
We all know that Backbone.ModelBinding will handle the binding between the form inputs and the model that is bound to the add/edit view. However, the big box that represents our medication in the “Current Medications” list was not updated automatically. In order to get this to update, we had to re-render the view with the updated model.
Here’s what that code looks like (using an event aggregator in this case):
Not bad – pretty standard backbone code, really. My medication view re-renders itself when the model has been saved. Except I don’t think we should have to re-render the entire view just to update a few fields on the form.
Data-Bind Your Way To Happiness
Let’s try this again with my new data bind convention in place.
from 27 lines of code down to 13? Now that’s more like it!
But more important than the number of lines of code, you’ll notice that there’s no view re-rendering happening for the medication view. I’ve also removed the use of the event aggregator from this scenario. That’s because we don’t need to re-render the entire view when the model is updated, and we don’t need to wait for the event aggregator to tell us that the model was updated. We can let our data-bind conventions work their magic and update the medication view as changes are being made!
So, then… how do we get this magic to work? First off, we need to build the data-bind convention:
Drop this code into your project, somewhere. Be sure it is executed after the Backbone.ModelBinding.js file has been loaded so that the very last line can correctly attach the new DataBindConvention to the convention list (also checkout the readme on the github repo for more information on this convention’s structure).
Once we have that in place, we just need to add some data-bind attributes to our html. Here’s an approximation of what the html for the above medication view looks like:
The key here is the ‘data-bind’ attribute that I’ve added to the divs that are displaying the model’s data. The data-bind convention that we set up looks for this attribute and then parses the information in it to set up the databinding. The first word of the attribute’s value tells our convention how to modify the element. The second word tells the convention which model attribute to use for the element’s value. In this case, we’re setting the text attribute of the divs to the model attribute that represents the data we want: ‘trade_name’ (the name of the drug), ‘dosage’ and ‘route’.
Now when we update our form by typing into the text boxes and then causing the text box to lose focus (so that the ‘change’ event can fire), our medication view updates instantly!
As I tabbed out of the “Trade name” field and into the “Dosage” field, the medication view updated and showed the change in the medication’s name!
A Pale Reflection, A Glimpse Of What’s To Come
I realize that what I’ve built is only a pale reflection of what Knockout offers for it’s data-binding capabilties. However, what I’ve shown is already helping me simplifiy my applications, reduce the amount of code that I’m writing, and improve the user experience.
There’s a lot of work left to do with this convention before I bake it in, permanently. There are some additional behaviors to add to this convention and there are some tweaks to be made to the existing code. For example – better handle drop lists which right now, always end up displaying the “value” of the seelction instead of the text of the selection. I also want to explore what Brandon Satrom is building for Knockout, to remove the use of the data-bind attributes. I may be able to leverage what he’s building to help improve what I’m building.
I need to talk about how to build a proper cancel operation for this form, as well.. After all, we don’t want the medication view to continue displaying the modified information if we hit the “close” link instead of the “Save” button… but that’s another blog post (coming soon).
For now, you can grab the source for this data-binding convention from the gist and start playing with data-bind for backbone it in your own application!