@@ -14,6 +14,7 @@ import {
14
14
merge ,
15
15
MonoTypeOperatorFunction ,
16
16
Observable ,
17
+ pairwise ,
17
18
ReplaySubject ,
18
19
Subject ,
19
20
} from 'rxjs' ;
@@ -143,6 +144,23 @@ export class AutoSizeVirtualScrollStrategy<
143
144
extractSize ?: ( entry : ResizeObserverEntry ) => number ;
144
145
} ;
145
146
147
+ /**
148
+ * @description
149
+ * When enabled, the autosized scroll strategy attaches a `ResizeObserver`
150
+ * to every view within the given renderedRange. If your views receive
151
+ * dimension changes that are not caused by list updates, this is a way to
152
+ * still track height changes. This also applies to resize events of the whole
153
+ * document.
154
+ */
155
+ @Input ( )
156
+ set withResizeObserver ( input : boolean ) {
157
+ this . _withResizeObserver = input != null && `${ input } ` !== 'false' ;
158
+ }
159
+ get withResizeObserver ( ) : boolean {
160
+ return this . _withResizeObserver ;
161
+ }
162
+ private _withResizeObserver = true ;
163
+
146
164
/**
147
165
* @description
148
166
* When enabled, the autosized scroll strategy removes css styles that
@@ -358,6 +376,15 @@ export class AutoSizeVirtualScrollStrategy<
358
376
// the IterableDiffer approach, especially on move operations
359
377
const itemCache = new Map < any , { item : T ; index : number } > ( ) ;
360
378
const trackBy = this . viewRepeater ! . _trackBy ?? ( ( i , item ) => item ) ;
379
+ this . renderedRange$
380
+ . pipe ( pairwise ( ) , this . until$ ( ) )
381
+ . subscribe ( ( [ oldRange , newRange ] ) => {
382
+ for ( let i = oldRange . start ; i < oldRange . end ; i ++ ) {
383
+ if ( i < newRange . start || i >= newRange . end ) {
384
+ this . _virtualItems [ i ] . position = undefined ;
385
+ }
386
+ }
387
+ } ) ;
361
388
this . viewRepeater ! . values$ . pipe (
362
389
this . until$ ( ) ,
363
390
tap ( ( values ) => {
@@ -388,7 +415,11 @@ export class AutoSizeVirtualScrollStrategy<
388
415
// todo: properly determine update (Object.is?)
389
416
virtualItems [ i ] = this . _virtualItems [ i ] ;
390
417
// if index is not part of rendered range, remove cache
391
- if ( i < this . renderedRange . start || i >= this . renderedRange . end ) {
418
+ if (
419
+ ! this . withResizeObserver ||
420
+ i < this . renderedRange . start ||
421
+ i >= this . renderedRange . end
422
+ ) {
392
423
virtualItems [ i ] . cached = false ;
393
424
}
394
425
itemCache . set ( id , { item : dataArr [ i ] , index : i } ) ;
@@ -650,22 +681,11 @@ export class AutoSizeVirtualScrollStrategy<
650
681
} )
651
682
) ;
652
683
const positionByResizeObserver$ = viewsToObserve$ . pipe (
684
+ filter ( ( ) => this . withResizeObserver ) ,
653
685
groupBy ( ( viewRef ) => viewRef ) ,
654
686
mergeMap ( ( o$ ) =>
655
687
o$ . pipe (
656
- exhaustMap ( ( viewRef ) =>
657
- this . observeViewSize$ ( viewRef ) . pipe (
658
- finalize ( ( ) => {
659
- if (
660
- this . _virtualItems [ viewRef . context . index ] ?. position !==
661
- undefined
662
- ) {
663
- this . _virtualItems [ viewRef . context . index ] . position =
664
- undefined ;
665
- }
666
- } )
667
- )
668
- ) ,
688
+ exhaustMap ( ( viewRef ) => this . observeViewSize$ ( viewRef ) ) ,
669
689
tap ( ( [ index , viewIndex ] ) => {
670
690
this . calcAnchorScrollTop ( ) ;
671
691
let position = this . calcInitialPosition ( index ) ;
0 commit comments