diff --git a/packages/@ember/-internals/metal/index.ts b/packages/@ember/-internals/metal/index.ts index 4b838b51aad..8e4d54a3dbf 100644 --- a/packages/@ember/-internals/metal/index.ts +++ b/packages/@ember/-internals/metal/index.ts @@ -38,6 +38,7 @@ export { } from './lib/descriptor_map'; export { watchKey, unwatchKey } from './lib/watch_key'; export { ChainNode, finishChains, removeChainWatcher } from './lib/chains'; +export { getChainTagsForKey } from './lib/chain-tags'; export { watchPath, unwatchPath } from './lib/watch_path'; export { isWatching, unwatch, watch, watcherCount } from './lib/watching'; export { default as libraries, Libraries } from './lib/libraries'; @@ -53,7 +54,7 @@ export { } from './lib/observer'; export { Mixin, aliasMethod, mixin, observer, applyMixin } from './lib/mixin'; export { default as inject, DEBUG_INJECTION_FUNCTIONS } from './lib/injected_property'; -export { tagForProperty, tagFor, markObjectAsDirty } from './lib/tags'; +export { tagForProperty, tagFor, markObjectAsDirty, UNKNOWN_PROPERTY_TAG } from './lib/tags'; export { default as runInTransaction, didRender, assertNotRendered } from './lib/transaction'; export { Tracker, tracked, getCurrentTracker, setCurrentTracker } from './lib/tracked'; diff --git a/packages/@ember/-internals/metal/lib/tags.ts b/packages/@ember/-internals/metal/lib/tags.ts index 56b412790f4..57b08f612ed 100644 --- a/packages/@ember/-internals/metal/lib/tags.ts +++ b/packages/@ember/-internals/metal/lib/tags.ts @@ -1,5 +1,5 @@ import { Meta, meta as metaFor } from '@ember/-internals/meta'; -import { isProxy } from '@ember/-internals/utils'; +import { isProxy, symbol } from '@ember/-internals/utils'; import { EMBER_METAL_TRACKED_PROPERTIES } from '@ember/canary-features'; import { backburner } from '@ember/runloop'; import { DEBUG } from '@glimmer/env'; @@ -12,6 +12,8 @@ import { UpdatableTag, } from '@glimmer/reference'; +export const UNKNOWN_PROPERTY_TAG = symbol('UNKNOWN_PROPERTY_TAG'); + function makeTag(): TagWrapper { return DirtyableTag.create(); } @@ -23,7 +25,11 @@ export function tagForProperty(object: any, propertyKey: string | symbol, _meta? } let meta = _meta === undefined ? metaFor(object) : _meta; - if (isProxy(object)) { + if (EMBER_METAL_TRACKED_PROPERTIES) { + if (!(propertyKey in object) && typeof object[UNKNOWN_PROPERTY_TAG] === 'function') { + return object[UNKNOWN_PROPERTY_TAG](propertyKey); + } + } else if (isProxy(object)) { return tagFor(object, meta); } diff --git a/packages/@ember/-internals/runtime/lib/mixins/-proxy.js b/packages/@ember/-internals/runtime/lib/mixins/-proxy.js index f895fa4d95e..3e5ed0d5316 100644 --- a/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +++ b/packages/@ember/-internals/runtime/lib/mixins/-proxy.js @@ -14,6 +14,8 @@ import { Mixin, tagFor, computed, + UNKNOWN_PROPERTY_TAG, + getChainTagsForKey, } from '@ember/-internals/metal'; import { setProxy } from '@ember/-internals/utils'; import { EMBER_METAL_TRACKED_PROPERTIES } from '@ember/canary-features'; @@ -85,6 +87,10 @@ export default Mixin.create({ } }, + [UNKNOWN_PROPERTY_TAG](key) { + return getChainTagsForKey(this, `content.${key}`); + }, + unknownProperty(key) { let content = contentFor(this); if (content) {