jridgewell/minionette

View on GitHub
docs/minionette.region.md

Summary

Maintainability
Test Coverage
Minionette.Region
=================

`Minionette.Region`s help manage subviews of a
[Minionette.View](/docs/minionette.view.md), allowing you to specify
directly in a template where a subview should be attached. A view can
have any number of regions, each managing their own part of the overall
view. All regions use an internal "placeholder" view that will be
present in the DOM generated by a render. Attaching a view to the region
will cause the entire placeholder to be replaced with the entire view,
meaning that subviews behave exactly like normal views with a top level
element defined in code.

```javascript
var View = Minionette.View.extend({
    regions: {
        'subView': '#subView',
        'other': null
    },
    template: _.template('<div id="subView"></div> <%= view("other") %>')
});

var v = new View();
v.render();
console.log(v.el) //=> <div id="subView"></div><span data-cid="123"></span>

console.log(v.subView.view.el); //=> <div id="subView"></div>
v.subView.attach(new Minionette.View({tagName: 'p'}));
console.log(v.subView.view.el); //=> <p></p>

console.log(v.other.view.el); //=> <span data-cid="123"></span>
v.other.attach(new Minionette.View({tagName: 'ul'}));
console.log(v.other.view.el); //=> <ul></ul>

console.log(v.el) //=> <p></p><ul></ul>
```


## #render()

The `#render()` method is a helper that delegates to the region's view.


## #attach(newView, detach = false)

The `#attach()` method attaches `newView` (top level element and all) to
the region in the exact same spot as the region's current view. It
optionally takes a `detach` parameter that, when true, will not call
`view.remove()` on the region's current view.

```javascript
var View = Minionette.View.extend({
    regions: {
        'subView': '#subView'
    },
    template: _.template('<div id="subView"></div>')
});

var v = new View();
v.render();
console.log(v.subView.view.el); //=> <div id="subView"></div>
v.subView.attach(new Minionette.View({tagName: 'p'}));
console.log(v.subView.view.el); //=> <p></p>
```

### "attach" Event

The "attach" event is fired before the region's current view is replaced
with the newView and before any DOM changes take place. The newView and
the region are passed as the arguments.

### "attached" Event

The "attached" event is fired after the region's current view is
replaced with the newView and after all DOM changes take place. The
newly attached view and the region are passed as the arguments.


## #reset(detach = false)

The `#reset()` method resets the region to using the placeholder view.
It optionally takes a `detach` parameter that, when true, will not call
`view.remove()` on the region's current view.

```javascript
var View = Minionette.View.extend({
    regions: {
        'subView': '#subView'
    },
    template: _.template('<div id="subView"></div>')
});

var v = new View();
v.render();
console.log(v.subView.view.el); //=> <div id="subView"></div>
v.subView.attach(new Minionette.View({tagName: 'p'}));
console.log(v.subView.view.el); //=> <p></p>
v.subView.reset();
console.log(v.subView.view.el); //=> <div id="subView"></div>
```


## #detach()

The `#detach()` method detaches the region's current view (storing a
reference to it internally) and replaces it with the placeholder. That
current view is stored internally so that you can call
[#reattach()](#reattach).  This is exceptionally useful during
rendering, since detaching the region will preserve the current view's
DOM event listeners.

```javascript
var View = Minionette.View.extend({
    regions: function() {
        return {'subView': new Minionette.View({tagName: 'ul'})};
    },
    template: _.template('<%= view("subView") %>')
});

var v = new View();
v.subView.view.on('test', function() {return 'it keeps events';});
v.render();

console.log(v.subView.view.el); //=> <ul></ul>
v.subView.detach()
console.log(v.subView.view.el); //=> <span data-cid="123"></span>

v.subView.reattach();
console.log(v.subView.view.el); //=> <ul></ul>

v.subView.view.trigger('test'); //=> 'it keeps events'
```

### "detach" Event

The "detach" event is fired before the region's current view is detached
and before any DOM changes take place. The current view and the region
are passed as the arguments.

### "detached" Event

The "detached" event is fired after the region's current view is
detached and after all DOM changes take place. The newly detached view
and the region are passed as the arguments.


## #reattach()

The `#reattach()` method takes the internally stored detached view (see
[#detach()](#detach)) and reinserts it into the parent view. See (see
[#detach()](#detach) for an example.)

### "reattach" Event

The "reattach" event is fired before the region's detached view is
reattached and before any DOM changes take place. The detached view and
the region are passed as the arguments.

### "reattached" Event

The "reattached" event is fired after the region's detached view is
reattached and after all DOM changes take place. The newly attached
view and the region are passed as the arguments.


## #remove()

The `#remove()` method removes the region (and subviews) from the
parent view.

### "remove" Event

The "remove" event is fired before calling `#remove()` on the subviews.
The region is passed at the only argument.

### "removed" Event

The "remove" event is fired after calling `#remove()` on the subviews.
The region is passed at the only argument.

Note that if you used `region.listenTo(region, 'removed', ...)`, the
listener will never be fired because `#remove()` calls
`#stopListening()`. To properly listen for this event, use
`region.on('removed', ...)`.