Backbone Views and the DOM

Final product image
What You'll Be Creating

Overview

Backbone views provide a useful convention and abstraction for user interfaces. However, to include UI functionality in your app that Backbone, on its own, was not designed to support, you’ll need to consider how to effectively integrate custom or third-party functionality into your Backbone app. As a result, developers must navigate challenges and avoid tricky conflicts between the external libraries and Backbone.

Intro to Backbone.js

Backbone is a fantastic way to organize your client-side code. With abstractions like models, views, and collections, Backbone helps serious developers write well-organized, scalable applications. 

While there are many alternatives to Backbone, including Angular and Ember, Backbone provides developers with incredible freedom to write and organize their code in natural and comfortable ways without being too opinionated about what the Document Object Model (DOM) looks like.

The Skinny on Backbone Views

Views are one of the most powerful and flexible components in Backbone. According to the authors of Backbone:

Backbone views are almost more convention than they are code — they don’t determine anything about your HTML or CSS for you, and can be used with any JavaScript templating library.

They are used to manipulate what users see in their browser, and they facilitate communication with models. As a result, in the paradigm of Model-View-Controller, it is useful to think about Backbone Views as both view and controller.

This has serious implications when developing applications with significant user interaction. In fact, there are many situations where you might want to use some other library to manipulate the DOM. Data visualization and web-based gaming are two examples where you might prefer to have another library handle some of your user-facing view rendering. As a result, you might consider using jQuery, d3.js, crossfilter, or three.js for some of your DOM manipulation needs.

Fortunately, there are ways to make Backbone play nicely with these other DOM manipulators.

Manipulating the Document Object Model in Backbone

Before we get into it, let’s review DOM manipulation in Backbone. Let’s start with a basic view object.

Great. Now, let’s tell the view how to render itself by defining a .render() method.

There are several things going on here, so let’s take it step by step.

Defining a .render() Method

First, we define a .render() method that encapsulates the logic necessary to render HTML. Note that Backbone comes with a .render() method out of the box. However, it doesn’t do anything. It was designed to be overwritten with custom logic!

Getting HTML Content

The above example assumes that you get HTML somewhere. You can use underscores _.template(). Alternatively, we can use other templating libraries, like Handlebars (my personal favorite). All that really matters is that, somehow, we get some HTML content.

What the Hell is el?

We need a place to put the HTML content; that’s what el is for. Like .render(), el is an attribute that comes with Backbone Views out of the box. It references the HTML element (and all its children) contained in this view. In the above example, we did not specify el. By default, el is a div. However, we could have easily set the parent element like so:

There is also $el, which is just el wrapped in jQuery. We'll see later on that $el plays a powerful role in mastering Backbone views.

Returning this

Finally, we return a reference to the object itself to allow for chaining. While not strictly required, returning this is a convention. Without return this, we would need some way to access the element’s HTML content. The following code illustrates an alternative solution.

Uhh, Nothing Is on the Screen!

Good point. Even though we called .render(), there isn’t anything on the screen—what gives?

That is because we haven’t interacted with the DOM yet. All we did was generate some HTML and represent it in a JavaScript object called aView. Since we now have access to the generated HTML, all we have to do is append or insert the HTML in your web app’s DOM.

To move things along, we’ll also set up a mini-app so that when the page loads, the view appears. Below are what your HTML and JavaScript should look like.

Basic HTML Setup

Here’s What Is Going On in App.js

Go to your local server/browser, load up the page, and your application should be running!

Using Backbone and jQuery Simultaneously

Backbone’s flexibility allows our use of third-party libraries to manipulate the DOM. One scenario is when you want to use jQuery and Backbone simultaneously to manipulate your views. Below is an updated example.

The code above will result in two paragraphs on the page. The first paragraph contains “Some HTML”. The second paragraph contains “Other HTML”.

To test your understanding of this, reverse the method calls like so:

The code above will result in one paragraph: “Some HTML”. In both cases, there is also a <p> element with nothing in it. We’ll discuss this in a moment.

Manipulating the DOM in Backbone Views Efficiently

Understanding the magic of efficient DOM manipulation (and traversal) requires an understanding of this.$el and this.$(). By using this.$el, we are scoping DOM manipulation to the content contained in the view. By using this.$(), we are scoping DOM traversal to the DOM tree within the view.

As a result, in the Backbone context, some uses of $() (instead of this.$()) could be inefficient. For example, let’s say we wanted to traverse the DOM to find some element. We might use any of the common DOM traversal methods, including .find(), .children(), .closest(), .first(), and so on.

If we know, a priori, that the element we seek lies somewhere within the view’s DOM, then we should use this.$() to avoid searching a larger DOM tree unnecessarily. If the element we seek lies outside of the view’s DOM, then we’ll need to use $().

For example, the .specialRender() method uses localized DOM traversal to ensure that we search for elements with class empty within the context of the view. If found, it sets the HTML content of those elements to include a span and the text "No longer empty".

Conclusion

In this article we reviewed Backbone views, discussed how to render Backbone views in the DOM, and explored how to make Backbone play nicely with other libraries you might want to use to manipulate the DOM. We also learned about localized DOM traversal and identified methods to efficiently and inefficiently traverse the DOM.

The next part of this article will delve deeper into more complicated examples of getting multiple libraries to work together in manipulating the DOM.

Tags:

Comments

Related Articles