diff --git a/store.js b/store.js index c5b569c6a8..292df39a08 100644 --- a/store.js +++ b/store.js @@ -20,24 +20,24 @@ function Store(state, options) { } assign(Store.prototype, { - _add: function(component, props) { + _add(component, props) { this._dependents.push({ component: component, props: props }); }, - _init: function(props) { - var state = {}; - for (var i = 0; i < props.length; i += 1) { - var prop = props[i]; + _init(props) { + const state = {}; + for (let i = 0; i < props.length; i += 1) { + const prop = props[i]; state['$' + prop] = this._state[prop]; } return state; }, - _remove: function(component) { - var i = this._dependents.length; + _remove(component) { + let i = this._dependents.length; while (i--) { if (this._dependents[i].component === component) { this._dependents.splice(i, 1); @@ -46,14 +46,52 @@ assign(Store.prototype, { } }, - _sortComputedProperties: function() { - var computed = this._computed; - var sorted = this._sortedComputedProperties = []; - var visited = blankObject(); - var currentKey; + _set(newState, changed) { + const previous = this._state; + this._state = assign(assign({}, previous), newState); + + for (let i = 0; i < this._sortedComputedProperties.length; i += 1) { + this._sortedComputedProperties[i].update(this._state, changed); + } + + this.fire('state', { + changed, + previous, + current: this._state + }); + + const dependents = this._dependents.slice(); // guard against mutations + for (let i = 0; i < dependents.length; i += 1) { + const dependent = dependents[i]; + const componentState = {}; + dirty = false; + + for (let j = 0; j < dependent.props.length; j += 1) { + const prop = dependent.props[j]; + if (prop in changed) { + componentState['$' + prop] = this._state[prop]; + dirty = true; + } + } + + if (dirty) dependent.component.set(componentState); + } + + this.fire('update', { + changed, + previous, + current: this._state + }); + }, + + _sortComputedProperties() { + const computed = this._computed; + const sorted = this._sortedComputedProperties = []; + const visited = blankObject(); + let currentKey; function visit(key) { - var c = computed[key]; + const c = computed[key]; if (c) { c.deps.forEach(dep => { @@ -71,26 +109,25 @@ assign(Store.prototype, { } } - for (var key in this._computed) { + for (const key in this._computed) { visit(currentKey = key); } }, - compute: function(key, deps, fn) { - var store = this; - var value; + compute(key, deps, fn) { + let value; - var c = { - deps: deps, - update: function(state, changed, dirty) { - var values = deps.map(function(dep) { + const c = { + deps, + update: (state, changed, dirty) => { + const values = deps.map(dep => { if (dep in changed) dirty = true; return state[dep]; }); if (dirty) { - var newValue = fn.apply(null, values); - if (store._differs(newValue, value)) { + const newValue = fn.apply(null, values); + if (this._differs(newValue, value)) { value = newValue; changed[key] = true; state[key] = value; @@ -99,63 +136,33 @@ assign(Store.prototype, { } }; - c.update(this._state, {}, true); - this._computed[key] = c; this._sortComputedProperties(); + + const state = assign({}, this._state); + const changed = {}; + c.update(state, changed, true); + this._set(state, changed); }, - fire: fire, + fire, - get: get, + get, - on: on, + on, - set: function(newState) { - var oldState = this._state, - changed = this._changed = {}, - dirty = false; + set(newState) { + const oldState = this._state; + const changed = this._changed = {}; + let dirty = false; - for (var key in newState) { - if (this._computed[key]) throw new Error("'" + key + "' is a read-only property"); + for (const key in newState) { + if (this._computed[key]) throw new Error(`'${key}' is a read-only property`); if (this._differs(newState[key], oldState[key])) changed[key] = dirty = true; } if (!dirty) return; - this._state = assign(assign({}, oldState), newState); - - for (var i = 0; i < this._sortedComputedProperties.length; i += 1) { - this._sortedComputedProperties[i].update(this._state, changed); - } - - this.fire('state', { - changed: changed, - current: this._state, - previous: oldState - }); - - var dependents = this._dependents.slice(); // guard against mutations - for (var i = 0; i < dependents.length; i += 1) { - var dependent = dependents[i]; - var componentState = {}; - dirty = false; - - for (var j = 0; j < dependent.props.length; j += 1) { - var prop = dependent.props[j]; - if (prop in changed) { - componentState['$' + prop] = this._state[prop]; - dirty = true; - } - } - - if (dirty) dependent.component.set(componentState); - } - - this.fire('update', { - changed: changed, - current: this._state, - previous: oldState - }); + this._set(newState, changed); } }); diff --git a/test/runtime/samples/store-computed-oncreate/_config.js b/test/runtime/samples/store-computed-oncreate/_config.js new file mode 100644 index 0000000000..5e58271bad --- /dev/null +++ b/test/runtime/samples/store-computed-oncreate/_config.js @@ -0,0 +1,11 @@ +import { Store } from '../../../../store.js'; + +export default { + 'skip-ssr': true, + + store: new Store(), + + html: ` +

Hello Brian!

+ ` +}; \ No newline at end of file diff --git a/test/runtime/samples/store-computed-oncreate/main.html b/test/runtime/samples/store-computed-oncreate/main.html new file mode 100644 index 0000000000..ce35a047b5 --- /dev/null +++ b/test/runtime/samples/store-computed-oncreate/main.html @@ -0,0 +1,10 @@ +

Hello {$name}!

+ + \ No newline at end of file