diff --git a/packages/ember-meta/lib/meta.ts b/packages/ember-meta/lib/meta.ts index a2e707cc338..7624866b922 100644 --- a/packages/ember-meta/lib/meta.ts +++ b/packages/ember-meta/lib/meta.ts @@ -321,12 +321,13 @@ export class Meta { : '', !this.isMetaDestroyed() ); - let ret = this._chains; + let { _chains: ret } = this; if (ret === undefined) { this._chains = ret = create(this.source); - if (this.parent !== null) { - let parentChains = this.parent.writableChains(create); + let { parent } = this; + if (parent !== null) { + let parentChains = parent.writableChains(create); parentChains.copyTo(ret); } } diff --git a/packages/ember-metal/tests/chains_test.js b/packages/ember-metal/tests/chains_test.js index 91aa9bfc2ab..95a7963fa74 100644 --- a/packages/ember-metal/tests/chains_test.js +++ b/packages/ember-metal/tests/chains_test.js @@ -1,6 +1,7 @@ import { addObserver, get, + set, ChainNode, finishChains, defineProperty, @@ -156,25 +157,26 @@ moduleFor( ['@test writable chains is not defined more than once'](assert) { assert.expect(0); - function didChange() {} - let obj = { - foo: { - bar: { - baz: { - value: 123, - }, + class Base { + constructor() { + finishChains(meta(this)); + } + + didChange() {} + } + + Base.prototype.foo = { + bar: { + baz: { + value: 123, }, }, }; - // Setup object like a constructor, which delays initializing values in chains - let parentMeta = meta(obj); - parentMeta.proto = obj; - // Define a standard computed property, which will eventually setup dependencies defineProperty( - obj, + Base.prototype, 'bar', computed('foo.bar', { get() { @@ -184,24 +186,25 @@ moduleFor( ); // Define some aliases, which will proxy chains along - defineProperty(obj, 'baz', alias('bar.baz')); - defineProperty(obj, 'value', alias('baz.value')); + defineProperty(Base.prototype, 'baz', alias('bar.baz')); + defineProperty(Base.prototype, 'value', alias('baz.value')); // Define an observer, which will eagerly attempt to setup chains and watch // their values. This follows the aliases eagerly, and forces the first // computed to actually set up its values/dependencies for chains. If // writableChains was not already defined, this results in multiple root // chain nodes being defined on the same object meta. - addObserver(obj, 'value', null, didChange); - - let childObj = Object.create(obj); + addObserver(Base.prototype, 'value', null, 'didChange'); - let childMeta = meta(childObj); + class Child extends Base {} - finishChains(childMeta); + let childObj = new Child(); - // If we can unwatch the root computed, then chains was not overwritten - unwatch(childObj, 'foo.bar'); + set(childObj, 'foo.bar', { + baz: { + value: 456, + }, + }); } } );