@@ -6,52 +6,112 @@ import {CdkVirtualScrollViewport} from './virtual-scroll-viewport';
6
6
7
7
/** Virtual scrolling strategy for lists with items of known fixed size. */
8
8
export class VirtualScrollFixedSizeStrategy implements VirtualScrollStrategy {
9
- private _viewport : CdkVirtualScrollViewport ;
10
-
11
- constructor ( public itemSize : number , public bufferSize : number ) { }
9
+ /** The attached viewport. */
10
+ private _viewport : CdkVirtualScrollViewport | null = null ;
11
+
12
+ /** The size of the items in the virtually scrolling list. */
13
+ private _itemSize : number ;
14
+
15
+ /** The number of buffer items to render beyond the edge of the viewport. */
16
+ private _bufferSize : number ;
17
+
18
+ /**
19
+ * @param itemSize The size of the items in the virtually scrolling list.
20
+ * @param bufferSize he number of buffer items to render beyond the edge of the viewport.
21
+ */
22
+ constructor ( itemSize : number , bufferSize : number ) {
23
+ this . _itemSize = itemSize ;
24
+ this . _bufferSize = bufferSize ;
25
+ }
12
26
13
- /** Initialize the strategy and specify the viewport it will be working with. */
14
- init ( viewport : CdkVirtualScrollViewport ) {
27
+ /**
28
+ * Attaches this scroll strategy to a viewport.
29
+ * @param viewport The viewport to attach this strategy to.
30
+ */
31
+ attach ( viewport : CdkVirtualScrollViewport ) {
15
32
this . _viewport = viewport ;
16
- this . _viewport . totalContentSize = this . _viewport . dataLength * this . itemSize ;
33
+ this . _updateTotalContentSize ( ) ;
17
34
this . _updateRenderedRange ( ) ;
18
35
}
19
36
20
- /** Re-initialize the strategy with the same viewport. */
21
- reinit ( ) {
22
- if ( this . _viewport ) {
23
- this . init ( this . _viewport ) ;
24
- }
37
+ /** Detaches this scroll strategy from the currently attached viewport. */
38
+ detach ( ) {
39
+ this . _viewport = null ;
25
40
}
26
41
42
+ /**
43
+ * Update the item size and buffer size.
44
+ * @param itemSize The size of the items in the virtually scrolling list.
45
+ * @param bufferSize he number of buffer items to render beyond the edge of the viewport.
46
+ */
47
+ updateItemAndBufferSize ( itemSize : number , bufferSize : number ) {
48
+ this . _itemSize = itemSize ;
49
+ this . _bufferSize = bufferSize ;
50
+ this . _updateTotalContentSize ( ) ;
51
+ this . _updateRenderedRange ( ) ;
52
+ }
53
+
54
+ /** Called when the viewport is scrolled (debounced using requestAnimationFrame). */
27
55
onContentScrolled ( ) {
28
56
this . _updateRenderedRange ( ) ;
29
57
}
30
58
59
+ /** Called when the length of the data changes. */
31
60
onDataLengthChanged ( ) {
32
- this . _viewport . totalContentSize = this . _viewport . dataLength * this . itemSize ;
61
+ this . _updateTotalContentSize ( ) ;
33
62
this . _updateRenderedRange ( ) ;
34
63
}
35
64
65
+ /** Update the viewport's total content size. */
66
+ private _updateTotalContentSize ( ) {
67
+ if ( ! this . _viewport ) {
68
+ return ;
69
+ }
70
+
71
+ this . _viewport . totalContentSize = this . _viewport . dataLength * this . _itemSize ;
72
+ } ;
73
+
74
+ /** Update the viewport's rendered range. */
36
75
private _updateRenderedRange ( ) {
76
+ if ( ! this . _viewport ) {
77
+ return ;
78
+ }
79
+
37
80
const scrollOffset = this . _viewport . measureScrollOffset ( ) ;
38
- const firstVisibleIndex = Math . floor ( scrollOffset / this . itemSize ) ;
81
+ const firstVisibleIndex = Math . floor ( scrollOffset / this . _itemSize ) ;
39
82
const range = this . _expandRange (
40
83
{ start : firstVisibleIndex , end : firstVisibleIndex } ,
41
- this . bufferSize ,
42
- Math . ceil ( this . _viewport . viewportSize / this . itemSize ) + this . bufferSize ) ;
84
+ this . _bufferSize ,
85
+ Math . ceil ( this . _viewport . viewportSize / this . _itemSize ) + this . _bufferSize ) ;
43
86
this . _viewport . renderedRange = range ;
44
- this . _viewport . renderedContentOffset = this . itemSize * range . start ;
87
+ this . _viewport . renderedContentOffset = this . _itemSize * range . start ;
45
88
}
46
89
90
+ /**
91
+ * Expand the given range by the given amount in either direction.
92
+ * @param range The range to expand
93
+ * @param expandStart The number of items to expand the start of the range by.
94
+ * @param expandEnd The number of items to expand the end of the range by.
95
+ * @return The expanded range.
96
+ */
47
97
private _expandRange ( range : Range , expandStart : number , expandEnd : number ) : Range {
98
+ if ( ! this . _viewport ) {
99
+ return { ...range } ;
100
+ }
101
+
48
102
const start = Math . max ( 0 , range . start - expandStart ) ;
49
103
const end = Math . min ( this . _viewport . dataLength , range . end + expandEnd ) ;
50
104
return { start, end} ;
51
105
}
52
106
}
53
107
54
108
109
+ /**
110
+ * Provider factory for `VirtualScrollFixedSizeStrategy` that simply extracts the already created
111
+ * `VirtualScrollFixedSizeStrategy` from the given directive.
112
+ * @param fixedSizeDir The instance of `CdkVirtualScrollFixedSize` to extract the
113
+ * `VirtualScrollFixedSizeStrategy` from.
114
+ */
55
115
export function _virtualScrollFixedSizeStrategyFactory ( fixedSizeDir : CdkVirtualScrollFixedSize ) {
56
116
return fixedSizeDir . _scrollStrategy ;
57
117
}
@@ -73,11 +133,10 @@ export class CdkVirtualScrollFixedSize implements OnChanges {
73
133
/** The number of extra elements to render on either side of the viewport. */
74
134
@Input ( ) bufferSize = 5 ;
75
135
136
+ /** The scroll strategy used by this directive. */
76
137
_scrollStrategy = new VirtualScrollFixedSizeStrategy ( this . itemSize , this . bufferSize ) ;
77
138
78
139
ngOnChanges ( ) {
79
- this . _scrollStrategy . itemSize = this . itemSize ;
80
- this . _scrollStrategy . bufferSize = this . bufferSize ;
81
- this . _scrollStrategy . reinit ( ) ;
140
+ this . _scrollStrategy . updateItemAndBufferSize ( this . itemSize , this . bufferSize ) ;
82
141
}
83
142
}
0 commit comments