Wrapping widgets of other libraries

Backbone is an incredibly powerful framework, but it can't do everything. If you want to add a calendar widget, a rich text editor, or a node tree to your site, you'll probably want to use another library, which can provide such a component for you (for example, jQuery UI, TinyMCE, or jsTree). However, just because you want to use a tool other than Backbone, it doesn't mean you have to give up all of the convenience and power of Backbone classes. In fact, there are a number of benefits of creating a Backbone View class that wraps your third-party component.

First, wrapping the component in a View allows you to specify a common way of using this component. For instance, let's say you wanted to use the JQuery UI calendar widget (or datepicker) in your site. In jQuery UI, if you want your calendar to include a month-picking control, you have to supply a changeMonth: true option in every place in your code that creates a calendar:

// File #1
$('#datepicker1').datepicker({changeMonth: true});
// File #2
$('#datepicker2').datepicker({changeMonth: true});

However, assume that you create a View class that wraps the datepicker widget as follows:

var CalendarView = Backbone.View.extend({
    initialize: function() {
        this.$el.datepicker({changeMonth: true});
    }
});

You can use this class anywhere in your code that needs a calendar, and you won't have to worry about forgetting to provide the changeMonth option:

// File #1
new CalendarView({el: '#datepicker1'});
// File #2
new CalendarView({el: '#datepicker2'});

If a completely different developer on your team wants to add a calendar, even if he knows nothing about jQuery UI or the changeMonth option, he'll still be able to create a calendar with the appropriate options for your site just by using the View you've created. This ability to encapsulate all logic related to a particular component and define your own interface for using it is another major benefit of this wrapping approach.

Yet another benefit is the ability to easily make changes to a component. For instance, let's say one day, we decide that we want all the calendars on our site to also have a year-picking drop-down (in other words, we want them all to have a changeYear: true option). Without a wrapping Backbone View, we'd have to find every place on our site that uses the datepicker widget and change its options, but with our View, we only have a single place in the code to update.

Of course, there are disadvantages to this technique as well. One obvious one is that if we add any components to our site that don't use the same options as the rest, such as a datepicker widget without a month selector, we'll need to refactor our wrapping View to allow for such a possibility.

Another problem is that wrapped components can remove themselves from the DOM without calling remove on their wrapping View, preventing this View from being garbage collected. Normally, this won't be a problem, as a few extra "zombie" Views widgets in the memory won't meaningfully impact performance. However, if you have a significant number of these wrapped widgets, then you may want to use the widget's event system to ensure that the wrapping View always has remove called on it when its wrapped widget leaves the page. For instance:

CalendarView = Backbone.View.extend({
    initialize: function() {
        this.$el.datepicker({
            changeMonth: true,
                         onClose: _.bind(function() {
                             this.remove();
                         }, this)
        });
    }
});

Finally, while hiding the details of a widget's usage inside a View may be convenient, it can also inadvertently hide relevant details about this widget from your fellow developers. For instance, a widget might have a certain side effect, but because other developers just use the widget's wrapping View and never read the original widget's documentation, they won't be aware of this side effect.

For this reason, it is important to ensure that such Views are properly documented. If the wrapped component has any sort of side effect, performance or otherwise, this side effect should also be carefully documented on the View itself or you should ensure that all developers on the team understand the workings of the underlying component.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.27.91