diff --git a/packages/core/src/data_sources/model/data_collection/ComponentDataCollection.ts b/packages/core/src/data_sources/model/data_collection/ComponentDataCollection.ts index 08b54e7a7..daba285ef 100644 --- a/packages/core/src/data_sources/model/data_collection/ComponentDataCollection.ts +++ b/packages/core/src/data_sources/model/data_collection/ComponentDataCollection.ts @@ -171,7 +171,6 @@ function getCollectionItems( [keyCollectionsStateMap]: collectionsStateMap, [keyIsCollectionItem]: true, draggable: false, - deepPropagate: [setCollectionStateMap(collectionsStateMap)], }, opt, ); @@ -179,6 +178,7 @@ function getCollectionItems( } blockSymbolMain!.set(keyCollectionsStateMap, collectionsStateMap); const instance = blockSymbolMain!.clone({ symbol: true }); + setCollectionStateMapAndPropagate(collectionsStateMap, collectionId)(instance); components.push(instance); } @@ -186,10 +186,53 @@ function getCollectionItems( return components; } +function setCollectionStateMapAndPropagate( + collectionsStateMap: DataCollectionStateMap, + collectionId: string | undefined, +) { + return (model: Component) => { + setCollectionStateMap(collectionsStateMap)(model); + + // Listener function for the 'add' event + const addListener = (component: Component) => { + setCollectionStateMapAndPropagate(collectionsStateMap, collectionId)(component); + }; + + // Generate a unique listener key + const listenerKey = `_hasAddListener${collectionId ? `_${collectionId}` : ''}`; + + // Add the 'add' listener if not already in the listeners array + if (!model.collectionStateListeners.includes(listenerKey)) { + model.listenTo(model.components(), 'add', addListener); + model.collectionStateListeners.push(listenerKey); + + // Add a 'remove' listener to clean up + model.listenTo(model.components(), 'remove', () => { + model.stopListening(model.components(), 'add', addListener); // Remove the 'add' listener + const index = model.collectionStateListeners.indexOf(listenerKey); + if (index > -1) { + model.collectionStateListeners.splice(index, 1); // Remove the listener key + } + }); + } + + // Recursively apply to all child components + model + .components() + ?.toArray() + .forEach((component: Component) => { + setCollectionStateMapAndPropagate(collectionsStateMap, collectionId)(component); + }); + }; +} + function setCollectionStateMap(collectionsStateMap: DataCollectionStateMap) { return (cmp: Component) => { cmp.set(keyIsCollectionItem, true); - cmp.set(keyCollectionsStateMap, collectionsStateMap); + cmp.set(keyCollectionsStateMap, { + ...cmp.get(keyCollectionsStateMap), + ...collectionsStateMap, + }); }; } diff --git a/packages/core/src/data_sources/model/data_collection/DataCollectionVariable.ts b/packages/core/src/data_sources/model/data_collection/DataCollectionVariable.ts index 6a9a64d8f..6ee2422f0 100644 --- a/packages/core/src/data_sources/model/data_collection/DataCollectionVariable.ts +++ b/packages/core/src/data_sources/model/data_collection/DataCollectionVariable.ts @@ -112,7 +112,6 @@ function resolveCollectionVariable( const collectionItem = collectionsStateMap[collectionId]; if (!collectionItem) { - em.logError(`Collection not found: ${collectionId}`); return ''; } diff --git a/packages/core/src/dom_components/model/Component.ts b/packages/core/src/dom_components/model/Component.ts index 33a10cfa4..599eb59c6 100644 --- a/packages/core/src/dom_components/model/Component.ts +++ b/packages/core/src/dom_components/model/Component.ts @@ -266,6 +266,7 @@ export default class Component extends StyleableModel { collection!: Components; componentDVListener: ComponentDynamicValueWatcher; accumulatedPropagatedProps: DeepPropagationArray = []; + collectionStateListeners: string[] = []; constructor(props: ComponentProperties = {}, opt: ComponentOptions) { const componentDVListener = new ComponentDynamicValueWatcher(undefined, { @@ -316,7 +317,6 @@ export default class Component extends StyleableModel { this.preInit(); this.initClasses(); this.listenTo(this, `change:${keyCollectionsStateMap}`, this.handleCollectionsMapStateChange); - this.propagateDeeplyFromParent(); this.initComponents(); this.initTraits(); this.initToolbar();