/**
* The backbone View reference
* @external Backbone-View
* @extends external:Backbone-Events
* @see {@link http://backbonejs.org/#View|Backbone.View}
*/
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['underscore', 'backbone', './templateRenderer', './Cell', './NestedCell', './registry'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('underscore'), require('backbone'), require('./templateRenderer'), require('./Cell'), require('./NestedCell'), require('./registry'));
} else {
root.Torso = root.Torso || {};
root.Torso.View = factory(root._, root.Backbone, root.Torso.Utils.templateRenderer, root.Torso.Cell, root.Torso.NestedCell, root.Torso.registry);
}
}(this, function(_, Backbone, templateRenderer, Cell, NestedCell, registry) {
'use strict';
var $ = Backbone.$;
/**
* ViewStateCell is a NestedCell that holds view state data and can trigger
* change events. These change events will propagate up and trigger on the view
* as well.
*
* @class ViewStateCell
* @extends {NestedCell}
*
* @param {Object} attrs the initial values to set on the cell - inherited from {@link NestedCell}.
* @param {Object} opts options for the cell.
* @param {external:Backbone-View} opts.view the view that these options are tied to.
*
* @see <a href="../annotated/modules/View.html">View Annotated Source</a>
*/
var ViewStateCell = NestedCell.extend(/** @lends ViewStateCell# */{
/**
* @constructs
* @param {Object} attrs the initial values to set on the cell - inherited from {@link NestedCell}.
* @param {Object} opts options for the cell.
* @param {external:Backbone-View} opts.view the view that these options are tied to.
*/
initialize: function(attrs, opts) {
opts = opts || {};
this.view = opts.view;
},
/**
* Retrigger view state change events on the view as well.
* @override
*/
trigger: function(name) {
if (name === 'change' || name.indexOf('change:') === 0) {
View.prototype.trigger.apply(this.view, arguments);
}
if (name.indexOf('change:hide:') === 0) {
this.view.render();
}
NestedCell.prototype.trigger.apply(this, arguments);
}
});
var View = Backbone.View.extend(/** @lends View# */{
/**
* Cell that can be used to save state for rendering the view.
* @type {ViewStateCell}
*/
viewState: null,
template: undefined,
feedback: null,
feedbackCell: null,
behaviors: null,
templateRendererOptions: undefined,
prepareFields: null,
injectionSites: null,
__behaviorInstances: null,
__childViews: null,
__sharedViews: null,
__isActive: false,
__isAttachedToParent: false,
__isDisposed: false,
__attachedCallbackInvoked: false,
__feedbackOnEvents: null,
__feedbackListenToEvents: null,
/**
* Array of feedback when-then-to's. Example:
* [{
* when: {'@fullName': ['change']},
* then: function(event) { return {text: this.feedbackCell.get('fullName')};},
* to: 'fullName-feedback'
* }]
* @private
* @property {Array} feedback
*/
/**
* Overrides constructor to create needed fields and invoke activate/render after initialization
*
* Generic View that deals with:
* - Creation of private collections
* - Lifecycle of a view
*
* @class View
* @extends {external:Backbone-View}
* @author ariel.wexler@vecna.com, kent.willis@vecna.com
* @constructs
*
* @see <a href="../annotated/modules/View.html">View Annotated Source</a>
*/
constructor: function(options) {
options = options || {};
this.viewState = new ViewStateCell({}, { view: this });
this.feedbackCell = new Cell();
this.__childViews = {};
this.__sharedViews = {};
this.__injectionSiteMap = {};
this.__feedbackOnEvents = [];
this.__feedbackListenToEvents = [];
this.template = options.template || this.template;
this.templateRendererOptions = options.templateRendererOptions || this.templateRendererOptions;
this.__initializeBehaviors(options);
this.trigger('initialize:begin');
Backbone.View.apply(this, arguments);
this.trigger('initialize:complete');
if (!options.noActivate) {
this.activate();
}