Region

A common use case is to swap between views in a common DOM element; this can be done by using the same el property in both views and calling the render() method on the view you want to see. But this way doesn't clean the memory and event bindings because both views will remain live in memory, even if they are not in the DOM.

A particularly useful scenario is when you need to switch between sub-applications, because sub-applications are rendered in the same DOM element normally. For example, when a user wants to edit contact information, he/she will click on an Edit button, and the current view will be replaced with an edit form.

Region

Figure 2.2: Swapping views with regions

To switch between views, a Region class could be used as shown next:

var mainRegion = new Region({el: '#main'});
var contactViewer = new ContactViewer({model: contact});

contactViewer.on('edit:contact', function(contact) {
  var editContact = new EditContactView({ model: contact });
  mainRegion.show(editContact);
});

mainRegion.show(contactViewer);

The Region object points to an existing DOM element; to show a view on that element, the show() method should be called on the Region object. Note that views don't have the el property set because regions will put the element in the DOM and not the View itself. This gives us an extra feature, views don't need to set an el property anymore and can be rendered on any available region.

A basic region manager can be implemented with this code:

class Region {
  constructor(options) {
    this.el = options.el;
  }

  // Closes any active view and render a new one
  show(view) {
    this.closeView(this.currentView);
    this.currentView = view;
    this.openView(view);
  }

  closeView(view) {
    // Only remove the view when the remove function
    // is available
    if (view && view.remove) {
      view.remove();
    }
  }

  openView(view) {
    // Be sure that this.$el exists
    this.ensureEl();

    // Render the view on the this.$el element
    view.render();
    this.$el.html(view.el);
  }

  // Create the this.$el attribute if do not exists
  ensureEl() {
    if (this.$el) return;
    this.$el = $(this.el);
  }

  // Close the Region and any view on it
  remove() {
    this.closeView(this.currentView);
  }
}

When the show() method is called, it closes the current view, if any, then assigns a new currentView and opens the view. When a view is open, Region ensures that the $el property exists, first calling the ensureEl() method. Then the interesting part happens:

view.render();
this.$el.html(view.el);

The Backbone documentation explains how views works:

All views have a DOM element at all times (the el property), whether they've already been inserted into the page or not. In this fashion, views can be rendered at any time, and inserted into the DOM all at once [...]

And that's what happens here: we render the view in memory first, calling view.render(), and then insert the result in the DOM pointed by the Region $el property.

A remove() method is implemented too, to make regions compatible with Backbone Views. When a region is removed, it needs to close the owned view too, so this allows us to do this easily.

Imagine that we have a region that owns a CollectionView with many views inside; when the remove() method is called on the region, it will call the remove() method on the CollectionView, which will call the remove() method on every child view.

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

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