Lets Build a Backbone Based Framework!!
I’ve been building large scale applications in Backbone for about 8 months now. In that time I’ve used throax as well as building custom solutions in backbone.
Last night, I live coded the creation of a demo backbone framework similar in features to Thorax. I’m going to walk you through how I’ve solved architectural problems in contructing a large scale backbone framework.
When building a large scale Backbone, there are several consderations to consider.
- How are we going to have templates load? Inline html declarations in the views do not scale
- how do we handle render?
- how do we handle child views?
By default, backboneView.render() is a noop. Its meant to be overidden. Backbone.Events gives us a nice set of methods to allow Backbone objects to listenTo() events off each other, However, the actual bindings and callbacks are left to the implimenter.
I like to use “text/template.”
1 2 3
Transforming these into working templates is fairly straightforward. For each script tag with type=”text/template”, run the template compiler over the html inside and store it somewhere. In this case I add a data-name attribute which will be the key for the hash I store the compiled template in.
1 2 3 4 5 6
In this version, I chose to use express + jade, Of course writing underscore templates in jade seemed a little odd so I delegated those to jade’s include statement. I know there are projects like jade-browserify so maybe I’ll eventually update this using just jade.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
The actual contents of the underscore templates in the *.html templates will now be compiled and loaded into “templates[data-name]” where I can access it later.
Creating our own Base Backbone Objects.
The first thing we want to do is determie the shared behavior of backbone objects in our app. For special cases we can overide them later. However, for the sake of time, we want some decalrative way of telling the object what template to use and a default render() method that we can use in most situations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
Next up we need to create a render function. Its arbitrary based on the particular needs of your application. For most purposes however, Its sufficiant to make a view’s model’s attributes available inside the templates.
1 2 3 4 5 6 7 8 9 10
Here’s a great first start. Now any View that extends BaseView will have a render. The only interface we must follow is that the View have a model and a tpl which tells the View how to resolve this.template.
Of course there’s a major component missing. Any good backbone framework has a way of embedding subViews. Turns out its sort of tricky.
The Lifecycle of a Backbone view in this case is to listen to changes on model and call render() which updates the view’s $el property. Thus its impossible to proceed until this.$el is completely demystified.
what is $el?
I’ve heard alot of confusion about the nature of ‘this.$el’. Typically, a Backbone View is a controller for a node. This node is a structure relevant to the document object model.
you may be familiar with a dom object if you’ve used jquery.
In much the same way, a backbone view is a controller for a dom object.
You may have seen the kickstart for a backbone app that involves doing a jquery lookup on a node and setting its html to your view’s $el property
Assuming the render() method of the view returns ‘this’, then calling it before calling the $el property guarantees that the dom object managed by the view will be updated before being placed in the dom. When render() is called again, it updates the contents of that $el. The $container has a reference to $el stored in it thus ensuring that calling render() will change the webpage to reflect the latest state of the model.
Extending out Render() to support subViews.
With the afformentioned definition of $el in mind, The best way to embed a subview (with string based template engines, you do something else with dom based ones.) is to do an initial render of the dom node marking off somehow places to embed subviews. Then afterwards, go back through the $el and systematically embed $el for each subview in their respective places.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
There’s a new things we’ve added to this version.
- There is now a ‘subView()’ helper being passed into context, this will generate the slug that we will look for when embedding a subview.
- After the $el is rendered, we are searching for dom elements with class subview
- for each subView, we find the name of the subview we embed in there given as view-[viewName] and look it up in the view’s subViews key/val lookup object. Its a property of teh parent view.
With this, we now have an easy way of supporting subviews.
1 2 3 4 5 6 7 8 9 10 11 12
In parentView’s template, its as simple as using out new subView helper
1 2 3 4 5 6 7 8 9
In the next installment in this series, we’ll build a base ControllerView class which we can use to render generic collections. Yes, they’ll be embedable as subviews in our BaseView.