@@ -84,8 +84,7 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
84
84
// }
85
85
let parentInjector : Injector ;
86
86
let parentAnchor : ViewContainerRef ;
87
- const parents : IgcNgElement [ ] = [ ] ;
88
- let parentConfig : ComponentConfig ;
87
+ const parents : WeakRef < IgcNgElement > [ ] = [ ] ;
89
88
const componentConfig = this . config ?. find ( x => x . component === this . _componentFactory . componentType ) ;
90
89
91
90
const configParents = componentConfig ?. parents
@@ -100,11 +99,11 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
100
99
reflectComponentType ( x . component ) . selector
101
100
] ) . join ( ',' ) ) ;
102
101
if ( node ) {
103
- parents . push ( node ) ;
102
+ parents . push ( new WeakRef ( node ) ) ;
104
103
}
105
104
}
106
105
// select closest of all possible config parents
107
- let parent = parents [ 0 ] ;
106
+ let parent = parents [ 0 ] ?. deref ( ) ;
108
107
109
108
// Collected parents may include direct Angular HGrids, so only wait for configured parent elements:
110
109
const configParent = configParents . find ( x => x . selector === parent ?. tagName . toLocaleLowerCase ( ) ) ;
@@ -185,38 +184,20 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
185
184
// componentRef should also likely be protected:
186
185
const componentRef = ( this as any ) . componentRef as ComponentRef < any > ;
187
186
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 ) ;
197
188
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 ) ;
206
196
}
207
-
197
+ } else {
208
198
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 ( ) ;
220
201
}
221
202
}
222
203
@@ -230,6 +211,16 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
230
211
this . _templateWrapperRef . destroy ( ) ;
231
212
this . _templateWrapperRef = null ;
232
213
}
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
+ } ) ;
233
224
} ) ;
234
225
}
235
226
@@ -359,10 +350,45 @@ class IgxCustomNgElementStrategy extends ComponentNgElementStrategy {
359
350
}
360
351
361
352
private addToParentCache ( parentElement : IgcNgElement , queryName : string ) {
362
- var cachedComponents = parentElement . ngElementStrategy . cachedChildComponents . get ( queryName ) || [ ] ;
353
+ const cachedComponents = parentElement . ngElementStrategy . cachedChildComponents . get ( queryName ) || [ ] ;
363
354
cachedComponents . push ( ( this as any ) . componentRef . instance ) ;
364
355
parentElement . ngElementStrategy . cachedChildComponents . set ( queryName , cachedComponents ) ;
365
356
}
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
+ }
366
392
//#endregion schedule query update
367
393
368
394
0 commit comments