diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/tracked-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/tracked-test.js index c701a34208c..48a1f0d5352 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/tracked-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/tracked-test.js @@ -14,6 +14,44 @@ import { Component } from '../../utils/helpers'; moduleFor( 'Component Tracked Properties', class extends RenderingTestCase { + '@test simple test using classic component'() { + let personId = 0; + class Person { + @tracked first; + @tracked last; + + constructor(first, last) { + this.id = personId++; + this.first = first; + this.last = last; + } + } + + class PersonComponent extends Component { + @tracked first; + @tracked last; + + get person() { + return new Person(this.first, this.last); + } + } + + this.registerComponent('person-wrapper', { + ComponentClass: PersonComponent, + template: '{{@first}} {{@last}} | {{this.person.first}} {{this.person.last}}', + }); + + this.render('', { + first: 'robert', + last: 'jackson', + }); + + this.assertText('robert jackson | robert jackson'); + + runTask(() => this.context.set('first', 'max')); + this.assertText('max jackson | max jackson'); + } + '@test simple test using glimmerish component'() { let personId = 0; class Person { diff --git a/packages/@ember/-internals/metal/lib/decorator.ts b/packages/@ember/-internals/metal/lib/decorator.ts index 3f22ae3909a..a493e52bca5 100644 --- a/packages/@ember/-internals/metal/lib/decorator.ts +++ b/packages/@ember/-internals/metal/lib/decorator.ts @@ -1,6 +1,5 @@ import { Meta, meta as metaFor, peekMeta } from '@ember/-internals/meta'; import { assert } from '@ember/debug'; -import { _WeakSet as WeakSet } from '@glimmer/util'; export type DecoratorPropertyDescriptor = (PropertyDescriptor & { initializer?: any }) | undefined; @@ -80,17 +79,11 @@ function DESCRIPTOR_SETTER_FUNCTION( name: string, descriptor: ComputedDescriptor ): (value: any) => void { - let func = function CPSETTER_FUNCTION(this: object, value: any): void { + return function CPSETTER_FUNCTION(this: object, value: any): void { return descriptor.set(this, name, value); }; - - CP_SETTER_FUNCS.add(func); - - return func; } -export const CP_SETTER_FUNCS = new WeakSet(); - export function makeComputedDecorator( desc: ComputedDescriptor, DecoratorClass: { prototype: object } diff --git a/packages/@ember/-internals/metal/lib/property_set.ts b/packages/@ember/-internals/metal/lib/property_set.ts index bec221166f5..aef085266ed 100644 --- a/packages/@ember/-internals/metal/lib/property_set.ts +++ b/packages/@ember/-internals/metal/lib/property_set.ts @@ -1,13 +1,8 @@ -import { - HAS_NATIVE_PROXY, - lookupDescriptor, - setWithMandatorySetter, - toString, -} from '@ember/-internals/utils'; +import { HAS_NATIVE_PROXY, setWithMandatorySetter, toString } from '@ember/-internals/utils'; import { assert } from '@ember/debug'; import EmberError from '@ember/error'; import { DEBUG } from '@glimmer/env'; -import { CP_SETTER_FUNCS } from './decorator'; +import { descriptorForProperty } from './decorator'; import { isPath } from './path_cache'; import { notifyPropertyChange } from './property_events'; import { _getPath as getPath, getPossibleMandatoryProxyValue } from './property_get'; @@ -72,11 +67,10 @@ export function set(obj: object, keyName: string, value: any, tolerant?: boolean return setPath(obj, keyName, value, tolerant); } - let descriptor = lookupDescriptor(obj, keyName); - let setter = descriptor === null ? undefined : descriptor.set; + let descriptor = descriptorForProperty(obj, keyName); - if (setter !== undefined && CP_SETTER_FUNCS.has(setter)) { - obj[keyName] = value; + if (descriptor !== undefined) { + descriptor.set(obj, keyName, value); return value; } diff --git a/packages/@ember/-internals/metal/lib/tracked.ts b/packages/@ember/-internals/metal/lib/tracked.ts index 614297cbbeb..e7399ead097 100644 --- a/packages/@ember/-internals/metal/lib/tracked.ts +++ b/packages/@ember/-internals/metal/lib/tracked.ts @@ -5,7 +5,6 @@ import { DEBUG } from '@glimmer/env'; import { consumeTag, dirtyTagFor, tagFor, trackedData } from '@glimmer/validator'; import { CHAIN_PASS_THROUGH } from './chain-tags'; import { - CP_SETTER_FUNCS, Decorator, DecoratorPropertyDescriptor, isElementDescriptor, @@ -183,10 +182,21 @@ function descriptorForField([target, key, desc]: [ set, }; - metaFor(target).writeDescriptors(key, newDesc); - - CP_SETTER_FUNCS.add(set); - CHAIN_PASS_THROUGH.add(newDesc); + metaFor(target).writeDescriptors(key, new TrackedDescriptor(get, set)); return newDesc; } + +class TrackedDescriptor { + constructor(private _get: () => unknown, private _set: (value: unknown) => void) { + CHAIN_PASS_THROUGH.add(this); + } + + get(obj: object) { + return this._get.call(obj); + } + + set(obj: object, _key: string, value: unknown) { + this._set.call(obj, value); + } +}