diff --git a/packages/metal-state/src/State.js b/packages/metal-state/src/State.js index 9340e2ae..2d866082 100644 --- a/packages/metal-state/src/State.js +++ b/packages/metal-state/src/State.js @@ -271,8 +271,6 @@ class State extends EventEmitter { /** * Adds state keys from super classes static hint `MyClass.STATE = {};`. - * @param {Object.=} opt_config An object that maps all the - * configurations for state keys. * @protected */ configStateFromStaticHint_() { @@ -280,8 +278,13 @@ class State extends EventEmitter { if (ctor !== State) { let defineContext; if (this.obj_ === this) { - defineContext = ctor.hasConfiguredState_ ? false : ctor.prototype; - ctor.hasConfiguredState_ = true; + const staticKey = State.STATE_STATIC_HINT_CONFIGURED; + + ctor[staticKey] = ctor[staticKey] || {}; + + defineContext = ctor[staticKey][ctor.name] ? false : + ctor.prototype; + ctor[staticKey][ctor.name] = true; } this.configState(State.getStateStatic(ctor), defineContext); } @@ -676,8 +679,20 @@ class State extends EventEmitter { } } +/** + * Constant used as key on State instance for storing property definition. + * @type {!string} + */ State.STATE_REF_KEY = '__METAL_STATE_REF_KEY__'; +/** + * Constant used as key on class constructors that extend from State, stores + * which constructors have had their static STATE configured so that + * configuration of STATE is not repeated. + * @type {!string} + */ +State.STATE_STATIC_HINT_CONFIGURED = '__METAL_STATE_STATIC_HINT_CONFIGURED__'; + /** * Constants that represent the states that a state key can be in. * @type {!Object} diff --git a/packages/metal-state/test/State.js b/packages/metal-state/test/State.js index dbf8caf8..d5898904 100644 --- a/packages/metal-state/test/State.js +++ b/packages/metal-state/test/State.js @@ -1041,6 +1041,32 @@ describe('State', function() { assert.strictEqual('foo2', test2.key1); assert.strictEqual('foo1', test1.key1); }); + + it('should configure static STATE with multiple levels of class inheritance', function() { + var Test = createTestClass(); + Test.STATE = { + key1: { + } + }; + + class Child extends Test { + } + Child.STATE = { + key2: { + } + }; + + var test = new Test({ + key1: 'foo1' + }); + assert.strictEqual('foo1', test.key1); + + var child = new Child({ + key2: 'foo2' + }); + assert.strictEqual('foo1', test.key1); + assert.strictEqual('foo2', child.key2); + }); }); describe('Separate object', function() {