Skip to content

Commit

Permalink
feat: Add Component#onAdd, Component#onRemove
Browse files Browse the repository at this point in the history
Currently the onMount abstraction is broken.

onMount is being called in two completely different scenarios:

 1. The component has been added to a node.
 2. The node has been mounted.

The same is true for onShow.

This commit introduces two methods to solve this issue:

 1. Component#onAdd
 2. Component#onRemove
  • Loading branch information
alexanderGugel committed Jun 4, 2015
1 parent e78d68e commit c9fd487
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
51 changes: 44 additions & 7 deletions core/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,60 @@
* @constructor
* @abstract
*
* @param {Node} node Node to which the component should be added.
* @param {Node} [node] Node to which the component should be added.
*/
function Component(node) {
if (!node) throw new Error(
'Component must be instantiated on a Node'
);

/** @protected */
this._node = node;
this._node = null;

/** @protected */
this._id = this._node.addComponent(this);
this._id = null;

/** @protected */
this._requestingUpdate = false;

if (node) this.onAdd(node, node.addComponent(this));
}

/**
* Method that will be called by the node after the component has been added
* to it.
*
* @method
*
* @param {Node} node Node to which the component has been added.
* @param {Number} id The id under which the component has been
* registered.
* @return {undefined} undefined
*/
Component.prototype.onAdd = function onAdd(node, id) {
// Safety check needed for now to ensure backwards compatibility.
if (this._node === node && this._id === id) return;

if (this._node) throw new Error(
'Can not add component to multiple nodes.'
);

this._node = node;
this._id = id;
};

/**
* Method that will be called by the node after the component has been added
* to it.
*
* @method
*
* @param {Node} node Node from which the component has been removed.
* @param {Number} id The under which the component has previously been
* registered before being removed.
* @return {undefined} undefined
*/
Component.prototype.onRemove = function onRemove(node, id) {
this._node = null;
this._id = null;
};

/**
* Requests a new update from the Node. This results into the component's
* `onUpdate` method being called on the next
Expand Down
13 changes: 4 additions & 9 deletions core/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -614,11 +614,8 @@ Node.prototype.addComponent = function addComponent (component) {
index = this._freedComponentIndicies.length ? this._freedComponentIndicies.pop() : this._components.length;
this._components[index] = component;

if (this.isMounted() && component.onMount)
component.onMount(this, index);

if (this.isShown() && component.onShow)
component.onShow();
if (component.onAdd)
component.onAdd(this, index);
}

return index;
Expand Down Expand Up @@ -650,11 +647,9 @@ Node.prototype.removeComponent = function removeComponent (component) {
var index = this._components.indexOf(component);
if (index !== -1) {
this._freedComponentIndicies.push(index);
if (this.isShown() && component.onHide)
component.onHide();

if (this.isMounted() && component.onDismount)
component.onDismount();
if (component.removeComponent)
component.removeComponent(this, index);

this._components[index] = null;
}
Expand Down
4 changes: 4 additions & 0 deletions dom-renderables/DOMElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ var RENDER_SIZE = 2;
* for DOM and WebGL layering. On by default.
*/
function DOMElement(node, options) {
if (!node) throw new Error(
'DOMElement must be instantiated on a Node'
);

Component.call(this, node);

this._renderSized = false;
Expand Down

0 comments on commit c9fd487

Please sign in to comment.