Jellyvision/lateralus

View on GitHub
docs/lateralus.component.js.html

Summary

Maintainability
Test Coverage
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>lateralus.component.js - Documentation</title>

    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav>
    <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Tutorials</li><li class="nav-item"><a href="tutorial-using-lateralus.html">Using Lateralus</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Lateralus.html">Lateralus</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#.beget">beget</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#.inherit">inherit</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#dispose">dispose</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#error">error</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#initRouter">initRouter</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#log">log</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#shareWith">shareWith</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#toString">toString</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.html#warn">warn</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Lateralus.Component.html">Lateralus.Component</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.html#dispose">dispose</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.html#extend">extend</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.html#toString">toString</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Lateralus.Component.Collection.html">Lateralus.Component.Collection</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.Collection.html#remove">remove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.Collection.html#toString">toString</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Lateralus.Component.Model.html">Lateralus.Component.Model</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.Model.html#destroy">destroy</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.Model.html#dispose">dispose</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.Model.html#toString">toString</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Lateralus.Component.View.html">Lateralus.Component.View</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.View.html#addSubview">addSubview</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.View.html#deferredInitialize">deferredInitialize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.View.html#dispose">dispose</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.View.html#getTemplateRenderData">getTemplateRenderData</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.View.html#initialize">initialize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.View.html#renderTemplate">renderTemplate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Component.View.html#toString">toString</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Lateralus.Model.html">Lateralus.Model</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Model.html#onChange">onChange</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Model.html#toString">toString</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Lateralus.Router.html">Lateralus.Router</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.Router.html#toString">toString</a></span></li><li class="nav-heading">Mixins</li><li class="nav-heading"><span class="nav-item-type type-mixin">M</span><span class="nav-item-name"><a href="Lateralus.mixins.html">Lateralus.mixins</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#addComponent">addComponent</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#amplify">amplify</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#collect">collect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#collectOne">collectOne</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#delegateLateralusEvents">delegateLateralusEvents</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#emit">emit</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#initCollection">initCollection</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#initModel">initModel</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#listenFor">listenFor</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Lateralus.mixins.html#mixin">mixin</a></span></li>
</nav>

<div id="main">
    
    <h1 class="page-title">lateralus.component.js</h1>
    

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>import _ from 'lodash-compat';
import Backbone from 'backbone';
import mixins from './lateralus.mixins';
import ComponentView from './lateralus.component.view';
import ComponentModel from './lateralus.component.model';
import ComponentCollection from './lateralus.component.collection';

/**
 * The constructor for this method should not be called directly.  Instead, use
 * the `{@link Lateralus.mixins#addComponent}` mixin method:
 *
 *     const App = Lateralus.beget(function () {
 *       Lateralus.apply(this, arguments);
 *     });
 *
 *     const app = new App(document.getElementById('app'));
 *     const component = app.addComponent(Lateralus.Component);
 *
 *     console.log(component instanceof Lateralus.Component); // true
 * @class Lateralus.Component
 * @param {Lateralus} lateralus
 * @param {Object} options Values to attach to this `{@link
 * Lateralus.Component}` instance.  This object also get passed to the `{@link
 * Lateralus.Component.initialize}` method, if one is defined.
 * @param {Object} [options.modelAttributes] Any attributes to pre-populate
 * the `{@link Lateralus.Component.Model}`
 * instance with, if there is one.
 * @param {Object} [options.modelOptions] Any parameters to pass to the
 * `{@link Lateralus.Component.Model}`
 * instance, if there is one.
 * @param {Object} viewOptions The `options` Object to pass to the
 * `{@link Lateralus.Component.View}`
 * constructor.
 * @param {Lateralus.Component} [opt_parentComponent] The parent component of
 * this component, if any.
 * @mixes http://backbonejs.org/#Events
 * @mixes Lateralus.mixins
 * @constructs Lateralus.Component
 */
function Component (lateralus, options, viewOptions, opt_parentComponent) {

  /**
   * A reference to the central {@link Lateralus} instance.
   * @member Lateralus.Component#lateralus
   * @type {Lateralus}
   * @final
   */
  this.lateralus = lateralus;

  /**
   * If a `{@link Lateralus.Component}` has `mixins` defined on its `prototype`
   * before it is instantiated, the objects within `mixins` will be merged into
   * this `{@link  "Lateralus.Component}` at instantiation-time with `{@link
   * Lateralus.Component/mixin}`.
   * @property mixins
   * @type {Object|Array&lt;Object>|undefined}
   * @default undefined
   */
  if (this.mixins) {
    _.each(this.mixins, _.bind(this.mixin, this));
  }

  if (opt_parentComponent) {
    /**
     * If this is a subcomponent of another `{@link Lateralus.Component}`, this
     * property is a reference to the parent `{@link Lateralus.Component}`.
     * @member Lateralus.Component#parentComponent
     * @type {Lateralus.Component|undefined}
     * @default undefined
     */
    this.parentComponent = opt_parentComponent;
  }

  /**
   * The `{@link Lateralus.Component.View}` constructor to use, if any.  If
   * this `{@link Lateralus.Component}` is intended to render to the DOM,
   * `View` should be defined on the `prototype` before instantiating:
   *
   *     const ExtendedComponent = Lateralus.Component.extend({
   *       name: 'extended',
   *       View: Lateralus.Component.View,
   *       template: '&lt;div>&lt;/div>'
   *     });
   * @member Lateralus.Component#View
   * @type {Lateralus.Component.View|undefined}
   * @default undefined
   */
  if (this.View) {
    const augmentedViewOptions = viewOptions;

    // A model instance provided to addComponent takes precendence over the
    // prototype property.
    if (this.Model &amp;&amp; !viewOptions.model) {

      options.modelOptions = _.extend(options.modelOptions || {}, {
        lateralus: lateralus,
        component: this
      });

      this.model = new this.Model(
        options.modelAttributes,
        options.modelOptions
      );

      augmentedViewOptions.model = this.model;
    }

    /**
     * If `{@link Lateralus.Component.View}` is defined, this is an instance of
     * that constructor.
     * @member Lateralus.Component#view
     * @type {Lateralus.Component.View|undefined}
     * @default undefined
     */
    this.view = new this.View(
        lateralus,
        this,
        augmentedViewOptions
      );
  }

  _.extend(this, options);

  /**
   * A method to be called when this `{@link Lateralus.Component}` has been set
   * up.
   * @member Lateralus.Component#initialize
   * @type {Function|undefined}
   * @default undefined
   */
  if (this.initialize) {
    this.initialize(options);
  }

  this.delegateLateralusEvents();
}

const fn = Component.prototype;

Component.View = ComponentView;
Component.Model = ComponentModel;
Component.Collection = ComponentCollection;

/**
 * Create a `{@link Lateralus.Component}` subclass.
 * @method Lateralus.Component#extend
 * @param {Object} protoProps
 * @param {string} protoProps.name The name of this component.  It should have
 * no whitespace.
 * @param {Lateralus.Component.View} [protoProps.View] The `{@link
 * Lateralus.Component.View}` to render this component with.
 * @param {Lateralus.Component.Model} [protoProps.Model] The optional `{@link
 * Lateralus.Component.Model}` to be provided to `protoProps.View` when it is
 * instantiated.  This does nothing if `protoProps.View` is not defined.
 */
Component.extend = function (protoProps) {
  const extendedComponent = Backbone.Model.extend.call(this, protoProps);

  if (!protoProps.name) {
    throw new Error('A name was not provided to Component.extend.');
  }

  _.extend(extendedComponent, protoProps);

  return extendedComponent;
};

// Prototype members
//
_.extend(fn, Backbone.Events, mixins);

/**
 * The name of this component.  This is used internally by Lateralus.
 * @protected
 * @property name
 * @type string
 */
fn.name = 'component';

/**
 * @param {any} property
 * @param {Object} object
 * @private
 */
function removePropertyFromObject (property, object) {
  for (const propertyName in object) {
    if (object[propertyName] === property) {
      delete object[propertyName];
    }
  }
}

/**
 * Remove this `{@link Lateralus.Component}` from memory.  Also remove any
 * nested components added by `{@link Lateralus.mixins#addComponent}`.
 * @method Lateralus.Component#dispose
 */
fn.dispose = function () {
  _(this).lateralusDispose(() => {
    if (this.view) {
      this.view.dispose();
    }

    if (this.components) {
      _.invoke(this.components, 'dispose');
    }

    const parentComponent = this.parentComponent;
    if (parentComponent) {
      removePropertyFromObject(this, parentComponent.components);
    }

    if (_.contains(this.lateralus.components, this)) {
      removePropertyFromObject(this, this.lateralus);
    }
  });
};

/**
 * Meant to be overridden by subclasses.
 * @method Lateralus.Component#toJSON
 * @return {Object}
 */
fn.toJSON = function () {
  return {};
};

/**
 * @method Lateralus.Component#toString
 * @return {string} The name of this Component.  This is used internally by
 * Lateralus.
 */
fn.toString = function () {
  return this.name;
};

export default Component;
</code></pre>
        </article>
    </section>




</div>

<br class="clear">

<footer>
    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.3</a> on Thu Sep 07 2017 15:55:10 GMT-0500 (CDT) using the Minami theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>