I recently started to use Backbone.js in my frontend work. I just want to write down two important issues I meet when using Backbone.js.

Issue of setting ‘el’

‘el’ is the DOM element where the view will render. If you define it when creating or initializing a view, you use ‘this.$el’ to refer an element in the existing DOM tree. So all your operations change the REAL DOM tree.

However, what if we don’t set ‘el’ when creating a view? The answer is that it creates a new element ‘<div></div>’ in memory, which has NOT been inserted into the existing DOM tree.

This causes a big trouble. Why? Because your added element,

this.$el.html('your_added_element')
// or
this.$el.append('your_added_element')

cannot be found in the existing DOM tree:

$('your_added_element') // => undefined

You have to search your added element by writing:

$('your_added_element', this.$el)

Thus, you have two ways to create a view in Backbone.js:

  1. Modify the element in the existing DOM tree.
  2. Create a new element ‘<div></div>’. You can also create a new tag by specifying ‘tagName’, such as ‘li’.

Two ways of rendering views

Based on above discussions, we have two ways to render views:

Changing the existing DOM tree:

let view = new View({el: 'your_selector', model: model})
view.render() // change the DOM tree

Not changing the existing DOM tree and all operations happen in a newly created element in memory:

let subview = new View({model: model})
this.$el.find('your_selector').html(subview.render().el) // inject
// Or
this.$el.append(subview.render().el) // append

I prefer the second way: initialzing and injecting. However, a small trouble is that sometimes an empty ‘<div></div>’ has to be wrapped.

Further reading

There are two nice posts about how to render subviews efficiently and correctly in Backbone.js.