Skip to content

Commit

Permalink
Merge LayoutView into ItemView.
Browse files Browse the repository at this point in the history
Resolves #2253
  • Loading branch information
jamesplease committed Feb 4, 2015
1 parent 8f3e721 commit 5b617d0
Show file tree
Hide file tree
Showing 15 changed files with 273 additions and 293 deletions.
7 changes: 4 additions & 3 deletions api/item-view.yaml
Expand Up @@ -6,11 +6,12 @@ extends:
- Marionette.AbstractView

description: |
An `ItemView` is a view that represents a single item. That item may be a `Backbone.Model` or may be a `Backbone.Collection`. Whichever it is though, it will be treated as a single item.
An `ItemView` is the basic view of Marionette. It can be used to render a Model or Collection. In addition, ItemViews can create and manage child views through the use of
[Regions]((marionette.region.md)). Regions are containers for child views.
Please see [the Marionette.AbstractView documentation](marionette.Abstractview.md) for more information on available features and functionality.
ItemView extends from AbstractView. For the full API, refer to [the Marionette.AbstractView documentation](marionette.abstractview.md) for inherited methods and properties.
Additionally, interactions with Marionette.Region will provide features such as `onShow` callbacks, etc. Please see [the Region documentation](marionette.region.md) for more information.
Unlike Backbone Views, the ItemView Class emits many events. These are most often triggered when a ItemView is displayed as a child within another ItemView or CollectionView.
constructor:
description: |
Expand Down
1 change: 0 additions & 1 deletion src/build/bundled.js
Expand Up @@ -57,7 +57,6 @@
// @include ../item-view.js
// @include ../collection-view.js
// @include ../composite-view.js
// @include ../layout-view.js

// @include ../behavior.js
// @include ../behaviors.js
Expand Down
1 change: 0 additions & 1 deletion src/build/core.js
Expand Up @@ -52,7 +52,6 @@
// @include ../item-view.js
// @include ../collection-view.js
// @include ../composite-view.js
// @include ../layout-view.js

// @include ../behavior.js
// @include ../behaviors.js
Expand Down
159 changes: 155 additions & 4 deletions src/item-view.js
@@ -1,14 +1,23 @@
// Item View
// ---------

// A single item view implementation that contains code for rendering
// with underscore.js templates, serializing the view's model or collection,
// and calling several methods on extended views, such as `onRender`.
// The standard view. Includes view events, automatic rendering
// of Underscore templates, nested views, and more.
Marionette.ItemView = Marionette.AbstractView.extend({
regionClass: Marionette.Region,

options: {
destroyImmediate: false
},

// Setting up the inheritance chain which allows changes to
// Marionette.AbstractView.prototype.constructor which allows overriding
constructor: function() {
constructor: function(options) {
options = options || {};

this._firstRender = true;
this._initializeRegions(options);

Marionette.AbstractView.apply(this, arguments);
},

Expand Down Expand Up @@ -45,9 +54,21 @@ Marionette.ItemView = Marionette.AbstractView.extend({
// a very specific rendering for your view. In general, though,
// you should override the `Marionette.Renderer` object to
// change how Marionette renders views.
// Subsequent renders after the first will re-render all nested

This comment has been minimized.

Copy link
@paulfalgout

paulfalgout Apr 5, 2015

Member

I don't know that this is quite true. This seems to imply that any child views will be re-rendered, but subsequent renders will just reset the regions correct?

// views.
render: function() {
this._ensureViewIsIntact();

if (this._firstRender) {
// if this is the first render, don't do anything to
// reset the regions
this._firstRender = false;
} else {
// If this is not the first render call, then we need to
// re-initialize the `el` for each region
this._reInitializeRegions();
}

this.triggerMethod('before:render', this);

this._renderTemplate();
Expand Down Expand Up @@ -104,5 +125,135 @@ Marionette.ItemView = Marionette.AbstractView.extend({
this.$el.html(html);

return this;
},

// Add a single region, by name, to the layoutView
addRegion: function(name, definition) {
var regions = {};
regions[name] = definition;
return this._buildRegions(regions)[name];
},

// Add multiple regions as a {name: definition, name2: def2} object literal
addRegions: function(regions) {
this.regions = _.extend({}, this.regions, regions);
return this._buildRegions(regions);
},

// Remove a single region from the LayoutView, by name
removeRegion: function(name) {
delete this.regions[name];
return this.regionManager.removeRegion(name);
},

showChildView: function(regionName, view) {
return this.getRegion(regionName).show(view);
},

getChildView: function(regionName) {
return this.getRegion(regionName).currentView;
},

// Provides alternative access to regions
// Accepts the region name
// getRegion('main')
getRegion: function(region) {
return this.regionManager.get(region);
},

// Get all regions
getRegions: function(){
return this.regionManager.getRegions();
},

// Enable easy overriding of the default `RegionManager`
// for customized region interactions and business specific
// view logic for better control over single regions.
getRegionManager: function() {
return new Marionette.RegionManager();
},

// Handle destroying regions, and then destroy the view itself.
destroy: function() {
if (this.isDestroyed) { return this; }

// #2134: remove parent element before destroying the child views, so
// removing the child views doesn't retrigger repaints
if(this.getOption('destroyImmediate') === true) {
this.$el.remove();
}
this.regionManager.destroy();
return Marionette.AbstractView.prototype.destroy.apply(this, arguments);
},

// Internal method to initialize the regions that have been defined in a
// `regions` attribute on this layoutView.
_initializeRegions: function(options) {
var regions;
this._initRegionManager();

regions = Marionette._getValue(this.regions, this, [options]) || {};

// Enable users to define `regions` as instance options.
var regionOptions = this.getOption.call(options, 'regions');

// enable region options to be a function
regionOptions = Marionette._getValue(regionOptions, this, [options]);

_.extend(regions, regionOptions);

// Normalize region selectors hash to allow
// a user to use the @ui. syntax.
regions = this.normalizeUIValues(regions, ['selector', 'el']);

this.addRegions(regions);
},

// internal method to build regions
_buildRegions: function(regions) {
var defaults = {
regionClass: this.getOption('regionClass'),
parentEl: _.partial(_.result, this, 'el')
};

return this.regionManager.addRegions(regions, defaults);
},

// Internal method to re-initialize all of the regions by updating
// the `el` that they point to
_reInitializeRegions: function() {
this.regionManager.invoke('reset');
},

// Internal method to initialize the region manager
// and all regions in it
_initRegionManager: function() {
this.regionManager = this.getRegionManager();
this.regionManager._parent = this;

this.listenTo(this.regionManager, 'before:add:region', function(name) {
this.triggerMethod('before:add:region', name);
});

this.listenTo(this.regionManager, 'add:region', function(name, region) {
this[name] = region;
this.triggerMethod('add:region', name, region);
});

this.listenTo(this.regionManager, 'before:remove:region', function(name) {
this.triggerMethod('before:remove:region', name);
});

this.listenTo(this.regionManager, 'remove:region', function(name, region) {
delete this[name];
this.triggerMethod('remove:region', name, region);
});
},

_getImmediateChildren: function() {
return _.chain(this.regionManager.getRegions())
.pluck('currentView')
.compact()
.value();
}
});
176 changes: 0 additions & 176 deletions src/layout-view.js

This file was deleted.

0 comments on commit 5b617d0

Please sign in to comment.