@@ -84,8 +84,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
8484 // }
8585 let parentInjector : Injector ;
8686 let parentAnchor : ViewContainerRef ;
87- const parents : IgcNgElement [ ] = [ ] ;
88- let parentConfig : ComponentConfig ;
87+ const parents : WeakRef < IgcNgElement > [ ] = [ ] ;
8988 const componentConfig = this . config ?. find ( x => x . component === this . _componentFactory . componentType ) ;
9089
9190 const configParents = componentConfig ?. parents
@@ -100,11 +99,11 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
10099 reflectComponentType ( x . component ) . selector
101100 ] ) . join ( ',' ) ) ;
102101 if ( node ) {
103- parents . push ( node ) ;
102+ parents . push ( new WeakRef ( node ) ) ;
104103 }
105104 }
106105 // select closest of all possible config parents
107- let parent = parents [ 0 ] ;
106+ let parent = parents [ 0 ] ?. deref ( ) ;
108107
109108 // Collected parents may include direct Angular HGrids, so only wait for configured parent elements:
110109 const configParent = configParents . find ( x => x . selector === parent ?. tagName . toLocaleLowerCase ( ) ) ;
@@ -185,38 +184,20 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
185184 // componentRef should also likely be protected:
186185 const componentRef = ( this as any ) . componentRef as ComponentRef < any > ;
187186
188- for ( let i = 0 ; i < parents . length ; i ++ ) {
189- const parent = parents [ i ] ;
190-
191- // find the respective config entry
192- parentConfig = configParents . find ( x => x . selector === parent ?. tagName . toLocaleLowerCase ( ) ) ;
193-
194- if ( ! parentConfig ) {
195- continue ;
196- }
187+ const parentQueries = this . getParentContentQueries ( componentConfig , parents , configParents ) ;
197188
198- const componentType = this . _componentFactory . componentType ;
199- // TODO - look into more cases where query expects a certain base class but gets a subclass.
200- // Related to https://github.com/IgniteUI/igniteui-angular/pull/12134#discussion_r983147259
201- const contentQueries = parentConfig . contentQueries . filter ( x => x . childType === componentType || x . childType === componentConfig . provideAs ) ;
202-
203- for ( const query of contentQueries ) {
204- if ( i > 0 && ! query . descendants ) {
205- continue ;
189+ for ( const { parent, query } of parentQueries ) {
190+ if ( query . isQueryList ) {
191+ parent . ngElementStrategy . scheduleQueryUpdate ( query . property ) ;
192+ if ( this . angularParent ) {
193+ // Cache the component in the parent (currently only paginator for HGrid),
194+ // so it is kept in the query even when detached from DOM
195+ this . addToParentCache ( parent , query . property ) ;
206196 }
207-
197+ } else {
208198 const parentRef = await parent . ngElementStrategy [ ComponentRefKey ] ;
209- if ( query . isQueryList ) {
210- parent . ngElementStrategy . scheduleQueryUpdate ( query . property ) ;
211- if ( this . angularParent ) {
212- // Cache the component in the parent (currently only paginator for HGrid),
213- // so it is kept in the query even when detached from DOM
214- this . addToParentCache ( parent , query . property ) ;
215- }
216- } else {
217- parentRef . instance [ query . property ] = componentRef . instance ;
218- parentRef . changeDetectorRef . detectChanges ( ) ;
219- }
199+ parentRef . instance [ query . property ] = componentRef . instance ;
200+ parentRef . changeDetectorRef . detectChanges ( ) ;
220201 }
221202 }
222203
@@ -230,6 +211,16 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
230211 this . _templateWrapperRef . destroy ( ) ;
231212 this . _templateWrapperRef = null ;
232213 }
214+
215+ // also schedule query updates on all parents:
216+ this . getParentContentQueries ( componentConfig , parents , configParents )
217+ . filter ( x => x . parent ?. isConnected && x . query . isQueryList )
218+ . forEach ( ( { parent, query } ) => {
219+ parent . ngElementStrategy . scheduleQueryUpdate ( query . property ) ;
220+ if ( this . angularParent ) {
221+ this . removeFromParentCache ( parent , query . property ) ;
222+ }
223+ } ) ;
233224 } ) ;
234225 }
235226
@@ -359,10 +350,45 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
359350 }
360351
361352 private addToParentCache ( parentElement : IgcNgElement , queryName : string ) {
362- var cachedComponents = parentElement . ngElementStrategy . cachedChildComponents . get ( queryName ) || [ ] ;
353+ const cachedComponents = parentElement . ngElementStrategy . cachedChildComponents . get ( queryName ) || [ ] ;
363354 cachedComponents . push ( ( this as any ) . componentRef . instance ) ;
364355 parentElement . ngElementStrategy . cachedChildComponents . set ( queryName , cachedComponents ) ;
365356 }
357+
358+ private removeFromParentCache ( parentElement : IgcNgElement , queryName : string ) {
359+ let cachedComponents = parentElement . ngElementStrategy . cachedChildComponents . get ( queryName ) || [ ] ;
360+ cachedComponents = cachedComponents . filter ( x => x !== ( this as any ) . componentRef . instance ) ;
361+ parentElement . ngElementStrategy . cachedChildComponents . set ( queryName , cachedComponents ) ;
362+ }
363+
364+ /** Get all matching content questions from all parents */
365+ private getParentContentQueries ( componentConfig : ComponentConfig , parents : WeakRef < IgcNgElement > [ ] , configParents : ComponentConfig [ ] ) : { parent : IgcNgElement , query : ContentQueryMeta } [ ] {
366+ const queries : { parent : IgcNgElement , query : ContentQueryMeta } [ ] = [ ] ;
367+
368+ for ( let i = 0 ; i < parents . length ; i ++ ) {
369+ const parent = parents [ i ] ?. deref ( ) ;
370+
371+ // find the respective config entry
372+ const parentConfig = configParents . find ( x => x . selector === parent ?. tagName . toLocaleLowerCase ( ) ) ;
373+ if ( ! parentConfig ) {
374+ continue ;
375+ }
376+
377+ const componentType = this . _componentFactory . componentType ;
378+ // TODO - look into more cases where query expects a certain base class but gets a subclass.
379+ // Related to https://github.com/IgniteUI/igniteui-angular/pull/12134#discussion_r983147259
380+ const contentQueries = parentConfig . contentQueries . filter ( x => x . childType === componentType || x . childType === componentConfig . provideAs ) ;
381+
382+ for ( const query of contentQueries ) {
383+ if ( i > 0 && ! query . descendants ) {
384+ continue ;
385+ }
386+ queries . push ( { parent, query } ) ;
387+ }
388+ }
389+
390+ return queries ;
391+ }
366392 //#endregion schedule query update
367393
368394
0 commit comments