ng-virtual-list 16.3.1 → 16.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -18
- package/esm2022/lib/const/index.mjs +3 -2
- package/esm2022/lib/ng-virtual-list.component.mjs +62 -17
- package/esm2022/lib/utils/buffer-interpolation.mjs +27 -0
- package/esm2022/lib/utils/trackBox.mjs +54 -13
- package/fesm2022/ng-virtual-list.mjs +141 -28
- package/fesm2022/ng-virtual-list.mjs.map +1 -1
- package/lib/const/index.d.ts +2 -1
- package/lib/ng-virtual-list.component.d.ts +19 -5
- package/lib/utils/buffer-interpolation.d.ts +5 -0
- package/lib/utils/trackBox.d.ts +17 -1
- package/package.json +1 -1
|
@@ -42,7 +42,8 @@ var SnappingMethods;
|
|
|
42
42
|
})(SnappingMethods || (SnappingMethods = {}));
|
|
43
43
|
|
|
44
44
|
const DEFAULT_ITEM_SIZE = 24;
|
|
45
|
-
const
|
|
45
|
+
const DEFAULT_BUFFER_SIZE = 2;
|
|
46
|
+
const DEFAULT_MAX_BUFFER_SIZE = 100;
|
|
46
47
|
const DEFAULT_LIST_SIZE = 400;
|
|
47
48
|
const DEFAULT_SNAP = false;
|
|
48
49
|
const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
|
|
@@ -688,6 +689,33 @@ class CacheMap extends EventEmitter {
|
|
|
688
689
|
}
|
|
689
690
|
}
|
|
690
691
|
|
|
692
|
+
const DEFAULT_EXTRA = {
|
|
693
|
+
extremumThreshold: 2,
|
|
694
|
+
bufferSize: 10,
|
|
695
|
+
};
|
|
696
|
+
const bufferInterpolation = (currentBufferValue, array, value, extra) => {
|
|
697
|
+
const { extremumThreshold = DEFAULT_EXTRA.extremumThreshold, bufferSize = DEFAULT_EXTRA.bufferSize, } = extra ?? DEFAULT_EXTRA;
|
|
698
|
+
if (currentBufferValue < value) {
|
|
699
|
+
let i = 0;
|
|
700
|
+
while (i < extremumThreshold) {
|
|
701
|
+
array.push(value);
|
|
702
|
+
i++;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
array.push(value);
|
|
707
|
+
}
|
|
708
|
+
while (array.length >= bufferSize) {
|
|
709
|
+
array.shift();
|
|
710
|
+
}
|
|
711
|
+
const l = array.length;
|
|
712
|
+
let buffer = 0;
|
|
713
|
+
for (let i = 0; i < l; i++) {
|
|
714
|
+
buffer += array[i];
|
|
715
|
+
}
|
|
716
|
+
return Math.ceil(buffer / l);
|
|
717
|
+
};
|
|
718
|
+
|
|
691
719
|
const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
|
|
692
720
|
var ItemDisplayMethods;
|
|
693
721
|
(function (ItemDisplayMethods) {
|
|
@@ -696,6 +724,7 @@ var ItemDisplayMethods;
|
|
|
696
724
|
ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
|
|
697
725
|
ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
|
|
698
726
|
})(ItemDisplayMethods || (ItemDisplayMethods = {}));
|
|
727
|
+
const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
|
|
699
728
|
/**
|
|
700
729
|
* An object that performs tracking, calculations and caching.
|
|
701
730
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/16.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
|
|
@@ -765,6 +794,16 @@ class TrackBox extends CacheMap {
|
|
|
765
794
|
_previousTotalSize = 0;
|
|
766
795
|
_scrollDelta = 0;
|
|
767
796
|
get scrollDelta() { return this._scrollDelta; }
|
|
797
|
+
isAdaptiveBuffer = true;
|
|
798
|
+
_bufferSequenceExtraThreshold = DEFAULT_BUFFER_EXTREMUM_THRESHOLD;
|
|
799
|
+
_maxBufferSequenceLength = DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH;
|
|
800
|
+
_bufferSizeSequence = [];
|
|
801
|
+
_bufferSize = 0;
|
|
802
|
+
get bufferSize() { return this._bufferSize; }
|
|
803
|
+
_defaultBufferSize = 0;
|
|
804
|
+
_maxBufferSize = this._defaultBufferSize;
|
|
805
|
+
_resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
|
|
806
|
+
_resetBufferSizeTimer;
|
|
768
807
|
lifeCircle() {
|
|
769
808
|
this.fireChangeIfNeed();
|
|
770
809
|
this.lifeCircleDo();
|
|
@@ -858,14 +897,16 @@ class TrackBox extends CacheMap {
|
|
|
858
897
|
*/
|
|
859
898
|
getItemPosition(id, stickyMap, options) {
|
|
860
899
|
const opt = { fromItemId: id, stickyMap, ...options };
|
|
861
|
-
|
|
900
|
+
this._defaultBufferSize = opt.bufferSize;
|
|
901
|
+
this._maxBufferSize = opt.maxBufferSize;
|
|
902
|
+
const { scrollSize, isFromItemIdFound } = this.recalculateMetrics({
|
|
862
903
|
...opt,
|
|
863
904
|
dynamicSize: this._crudDetected || opt.dynamicSize,
|
|
864
905
|
previousTotalSize: this._previousTotalSize,
|
|
865
906
|
crudDetected: this._crudDetected,
|
|
866
907
|
deletedItemsMap: this._deletedItemsMap,
|
|
867
908
|
});
|
|
868
|
-
return scrollSize;
|
|
909
|
+
return isFromItemIdFound ? scrollSize : -1;
|
|
869
910
|
}
|
|
870
911
|
/**
|
|
871
912
|
* Updates the collection of display objects
|
|
@@ -875,6 +916,8 @@ class TrackBox extends CacheMap {
|
|
|
875
916
|
if (opt.dynamicSize) {
|
|
876
917
|
this.cacheElements();
|
|
877
918
|
}
|
|
919
|
+
this._defaultBufferSize = opt.bufferSize;
|
|
920
|
+
this._maxBufferSize = opt.maxBufferSize;
|
|
878
921
|
const metrics = this.recalculateMetrics({
|
|
879
922
|
...opt,
|
|
880
923
|
collection: items,
|
|
@@ -883,6 +926,7 @@ class TrackBox extends CacheMap {
|
|
|
883
926
|
deletedItemsMap,
|
|
884
927
|
});
|
|
885
928
|
this._delta += metrics.delta;
|
|
929
|
+
this.updateAdaptiveBufferParams(metrics, items.length);
|
|
886
930
|
this._previousTotalSize = metrics.totalSize;
|
|
887
931
|
this._deletedItemsMap = {};
|
|
888
932
|
this._crudDetected = false;
|
|
@@ -898,6 +942,27 @@ class TrackBox extends CacheMap {
|
|
|
898
942
|
getNearestItem(scrollSize, items, itemSize, isVertical) {
|
|
899
943
|
return this.getElementFromStart(scrollSize, items, this._map, itemSize, isVertical);
|
|
900
944
|
}
|
|
945
|
+
_previousScrollSize = 0;
|
|
946
|
+
updateAdaptiveBufferParams(metrics, totalItemsLength) {
|
|
947
|
+
this.disposeClearBufferSizeTimer();
|
|
948
|
+
const scrollSize = metrics.scrollSize + this._delta, delta = Math.abs(this._previousScrollSize - scrollSize);
|
|
949
|
+
this._previousScrollSize = scrollSize;
|
|
950
|
+
const bufferRawSize = Math.min(Math.floor(delta / metrics.typicalItemSize) * 5, totalItemsLength), minBufferSize = bufferRawSize < this._defaultBufferSize ? this._defaultBufferSize : bufferRawSize, bufferValue = minBufferSize > this._maxBufferSize ? this._maxBufferSize : minBufferSize;
|
|
951
|
+
this._bufferSize = bufferInterpolation(this._bufferSize, this._bufferSizeSequence, bufferValue, {
|
|
952
|
+
extremumThreshold: this._bufferSequenceExtraThreshold,
|
|
953
|
+
bufferSize: this._maxBufferSequenceLength,
|
|
954
|
+
});
|
|
955
|
+
this.startResetBufferSizeTimer();
|
|
956
|
+
}
|
|
957
|
+
startResetBufferSizeTimer() {
|
|
958
|
+
this._resetBufferSizeTimer = setTimeout(() => {
|
|
959
|
+
this._bufferSize = this._defaultBufferSize;
|
|
960
|
+
this._bufferSizeSequence = [];
|
|
961
|
+
}, this._resetBufferSizeTimeout);
|
|
962
|
+
}
|
|
963
|
+
disposeClearBufferSizeTimer() {
|
|
964
|
+
clearTimeout(this._resetBufferSizeTimer);
|
|
965
|
+
}
|
|
901
966
|
/**
|
|
902
967
|
* Calculates the position of an element based on the given scrollSize
|
|
903
968
|
*/
|
|
@@ -949,32 +1014,32 @@ class TrackBox extends CacheMap {
|
|
|
949
1014
|
* Calculates list metrics
|
|
950
1015
|
*/
|
|
951
1016
|
recalculateMetrics(options) {
|
|
952
|
-
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize,
|
|
953
|
-
const { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
|
|
1017
|
+
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
|
|
1018
|
+
const bufferSize = Math.max(minBufferSize, this._bufferSize), { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
|
|
954
1019
|
|| (typeof fromItemId === 'string' && fromItemId > '-1');
|
|
955
1020
|
let leftItemsOffset = 0, rightItemsOffset = 0;
|
|
956
1021
|
if (enabledBufferOptimization) {
|
|
957
1022
|
switch (this.scrollDirection) {
|
|
958
1023
|
case 1: {
|
|
959
1024
|
leftItemsOffset = 0;
|
|
960
|
-
rightItemsOffset =
|
|
1025
|
+
rightItemsOffset = bufferSize;
|
|
961
1026
|
break;
|
|
962
1027
|
}
|
|
963
1028
|
case -1: {
|
|
964
|
-
leftItemsOffset =
|
|
1029
|
+
leftItemsOffset = bufferSize;
|
|
965
1030
|
rightItemsOffset = 0;
|
|
966
1031
|
break;
|
|
967
1032
|
}
|
|
968
1033
|
case 0:
|
|
969
1034
|
default: {
|
|
970
|
-
leftItemsOffset = rightItemsOffset =
|
|
1035
|
+
leftItemsOffset = rightItemsOffset = bufferSize;
|
|
971
1036
|
}
|
|
972
1037
|
}
|
|
973
1038
|
}
|
|
974
1039
|
else {
|
|
975
|
-
leftItemsOffset = rightItemsOffset =
|
|
1040
|
+
leftItemsOffset = rightItemsOffset = bufferSize;
|
|
976
1041
|
}
|
|
977
|
-
let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, leftSizeOfAddedItems = 0, leftSizeOfUpdatedItems = 0, leftSizeOfDeletedItems = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex;
|
|
1042
|
+
let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, leftSizeOfAddedItems = 0, leftSizeOfUpdatedItems = 0, leftSizeOfDeletedItems = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex, isFromItemIdFound = false;
|
|
978
1043
|
// If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
|
|
979
1044
|
if (dynamicSize) {
|
|
980
1045
|
let y = 0, stickyCollectionItem = undefined, stickyComponentSize = 0;
|
|
@@ -1014,6 +1079,7 @@ class TrackBox extends CacheMap {
|
|
|
1014
1079
|
stickyCollectionItem = collectionItem;
|
|
1015
1080
|
}
|
|
1016
1081
|
if (id === fromItemId) {
|
|
1082
|
+
isFromItemIdFound = true;
|
|
1017
1083
|
targetDisplayItemIndex = i;
|
|
1018
1084
|
if (stickyCollectionItem && stickyMap) {
|
|
1019
1085
|
const { num } = this.getElementNumToEnd(i, collection, map, typicalItemSize, size, isVertical);
|
|
@@ -1146,9 +1212,9 @@ class TrackBox extends CacheMap {
|
|
|
1146
1212
|
}
|
|
1147
1213
|
itemsFromStartToScrollEnd = Math.floor(scrollSize / typicalItemSize);
|
|
1148
1214
|
itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
|
|
1149
|
-
leftItemLength = Math.min(itemsFromStartToScrollEnd,
|
|
1150
|
-
rightItemLength = itemsFromStartToDisplayEnd +
|
|
1151
|
-
? totalLength - itemsFromStartToDisplayEnd :
|
|
1215
|
+
leftItemLength = Math.min(itemsFromStartToScrollEnd, bufferSize);
|
|
1216
|
+
rightItemLength = itemsFromStartToDisplayEnd + bufferSize > totalLength
|
|
1217
|
+
? totalLength - itemsFromStartToDisplayEnd : bufferSize;
|
|
1152
1218
|
leftItemsWeight = leftItemLength * typicalItemSize;
|
|
1153
1219
|
rightItemsWeight = rightItemLength * typicalItemSize;
|
|
1154
1220
|
leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize;
|
|
@@ -1189,6 +1255,7 @@ class TrackBox extends CacheMap {
|
|
|
1189
1255
|
totalLength,
|
|
1190
1256
|
totalSize,
|
|
1191
1257
|
typicalItemSize,
|
|
1258
|
+
isFromItemIdFound,
|
|
1192
1259
|
};
|
|
1193
1260
|
return metrics;
|
|
1194
1261
|
}
|
|
@@ -1389,6 +1456,7 @@ class TrackBox extends CacheMap {
|
|
|
1389
1456
|
}
|
|
1390
1457
|
dispose() {
|
|
1391
1458
|
super.dispose();
|
|
1459
|
+
this.disposeClearBufferSizeTimer();
|
|
1392
1460
|
if (this._tracker) {
|
|
1393
1461
|
this._tracker.dispose();
|
|
1394
1462
|
}
|
|
@@ -1609,19 +1677,49 @@ class NgVirtualListComponent {
|
|
|
1609
1677
|
}
|
|
1610
1678
|
;
|
|
1611
1679
|
get direction() { return this._$direction.getValue(); }
|
|
1612
|
-
_$itemsOffset = new BehaviorSubject(DEFAULT_ITEMS_OFFSET);
|
|
1613
|
-
$itemsOffset = this._$itemsOffset.asObservable();
|
|
1614
1680
|
/**
|
|
1615
|
-
*
|
|
1681
|
+
* @deprecated "itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".
|
|
1616
1682
|
*/
|
|
1617
1683
|
set itemsOffset(v) {
|
|
1618
|
-
|
|
1684
|
+
throw Error('"itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".');
|
|
1685
|
+
}
|
|
1686
|
+
;
|
|
1687
|
+
_$bufferSize = new BehaviorSubject(DEFAULT_BUFFER_SIZE);
|
|
1688
|
+
$bufferSize = this._$bufferSize.asObservable();
|
|
1689
|
+
/**
|
|
1690
|
+
* Number of elements outside the scope of visibility. Default value is 2.
|
|
1691
|
+
*/
|
|
1692
|
+
set bufferSize(v) {
|
|
1693
|
+
if (this._$bufferSize.getValue() === v) {
|
|
1619
1694
|
return;
|
|
1620
1695
|
}
|
|
1621
|
-
this._$
|
|
1696
|
+
this._$bufferSize.next(v);
|
|
1622
1697
|
}
|
|
1623
1698
|
;
|
|
1624
|
-
get
|
|
1699
|
+
get bufferSize() { return this._$bufferSize.getValue(); }
|
|
1700
|
+
_maxBufferSizeTransform = (v) => {
|
|
1701
|
+
const bufferSize = this._$bufferSize.getValue();
|
|
1702
|
+
if (v === undefined || v <= bufferSize) {
|
|
1703
|
+
return bufferSize;
|
|
1704
|
+
}
|
|
1705
|
+
return v;
|
|
1706
|
+
};
|
|
1707
|
+
_$maxBufferSize = new BehaviorSubject(DEFAULT_MAX_BUFFER_SIZE);
|
|
1708
|
+
$maxBufferSize = this._$maxBufferSize.asObservable();
|
|
1709
|
+
/**
|
|
1710
|
+
* Maximum number of elements outside the scope of visibility. Default value is 100.
|
|
1711
|
+
* If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
|
|
1712
|
+
* The greater the scroll size, the more elements are allocated for rendering.
|
|
1713
|
+
*/
|
|
1714
|
+
set maxBufferSize(v) {
|
|
1715
|
+
const val = this._maxBufferSizeTransform(v);
|
|
1716
|
+
if (this._$maxBufferSize.getValue() === val) {
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1719
|
+
this._$maxBufferSize.next(val);
|
|
1720
|
+
}
|
|
1721
|
+
;
|
|
1722
|
+
get maxBufferSize() { return this._$maxBufferSize.getValue(); }
|
|
1625
1723
|
_$trackBy = new BehaviorSubject(TRACK_BY_PROPERTY_NAME);
|
|
1626
1724
|
$trackBy = this._$trackBy.asObservable();
|
|
1627
1725
|
/**
|
|
@@ -1743,7 +1841,7 @@ class NgVirtualListComponent {
|
|
|
1743
1841
|
$trackBy.pipe(takeUntilDestroyed(), tap(v => {
|
|
1744
1842
|
this._trackBox.trackingPropertyName = v;
|
|
1745
1843
|
})).subscribe();
|
|
1746
|
-
const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $
|
|
1844
|
+
const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = this.$bufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map(v => v < 0 ? DEFAULT_MAX_BUFFER_SIZE : v)), $stickyMap = this.$stickyMap.pipe(map(v => !v ? {} : v)), $snap = this.$snap, $isVertical = this.$direction.pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = this.$dynamicSize, $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $cacheVersion = this.$cacheVersion;
|
|
1747
1845
|
$isVertical.pipe(takeUntilDestroyed(), tap(v => {
|
|
1748
1846
|
this._isVertical = v;
|
|
1749
1847
|
const el = this._elementRef.nativeElement;
|
|
@@ -1756,12 +1854,12 @@ class NgVirtualListComponent {
|
|
|
1756
1854
|
this.listenCacheChangesIfNeed(dynamicSize);
|
|
1757
1855
|
})).subscribe();
|
|
1758
1856
|
combineLatest([this.$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
|
|
1759
|
-
$
|
|
1760
|
-
]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize,
|
|
1857
|
+
$bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
|
|
1858
|
+
]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
|
|
1761
1859
|
let actualScrollSize = (this._isVertical ? this._container?.nativeElement.scrollTop ?? 0 : this._container?.nativeElement.scrollLeft) ?? 0;
|
|
1762
1860
|
const { width, height } = bounds, opts = {
|
|
1763
1861
|
bounds: { width, height }, dynamicSize, isVertical, itemSize,
|
|
1764
|
-
|
|
1862
|
+
bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
|
|
1765
1863
|
}, { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, opts);
|
|
1766
1864
|
this.resetBoundsSize(isVertical, totalSize);
|
|
1767
1865
|
this.createDisplayComponentsIfNeed(displayItems);
|
|
@@ -1908,9 +2006,13 @@ class NgVirtualListComponent {
|
|
|
1908
2006
|
}
|
|
1909
2007
|
const { width, height } = this._$bounds.getValue() || { width: 0, height: 0 }, stickyMap = this.stickyMap, items = this.items, isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
|
|
1910
2008
|
bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
|
|
1911
|
-
|
|
2009
|
+
bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
|
|
1912
2010
|
snap: this.snap, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
|
|
1913
2011
|
}, scrollSize = this._trackBox.getItemPosition(id, stickyMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
2012
|
+
if (scrollSize === -1) {
|
|
2013
|
+
container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
2014
|
+
return;
|
|
2015
|
+
}
|
|
1914
2016
|
this._trackBox.clearDelta();
|
|
1915
2017
|
if (container) {
|
|
1916
2018
|
const { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, {
|
|
@@ -1922,6 +2024,10 @@ class NgVirtualListComponent {
|
|
|
1922
2024
|
this.createDisplayComponentsIfNeed(displayItems);
|
|
1923
2025
|
this.tracking();
|
|
1924
2026
|
const _scrollSize = this._trackBox.getItemPosition(id, stickyMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
|
|
2027
|
+
if (_scrollSize === -1) {
|
|
2028
|
+
container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
1925
2031
|
const notChanged = actualScrollSize === _scrollSize;
|
|
1926
2032
|
if (!notChanged || iteration < MAX_SCROLL_TO_ITERATIONS) {
|
|
1927
2033
|
this.clearScrollToRepeatExecutionTimeout();
|
|
@@ -1938,9 +2044,12 @@ class NgVirtualListComponent {
|
|
|
1938
2044
|
this._$scrollSize.next(scrollSize);
|
|
1939
2045
|
}
|
|
1940
2046
|
else {
|
|
1941
|
-
const index = items.findIndex(item => item.id === id)
|
|
1942
|
-
|
|
1943
|
-
|
|
2047
|
+
const index = items.findIndex(item => item.id === id);
|
|
2048
|
+
if (index > -1) {
|
|
2049
|
+
const scrollSize = index * this.itemSize;
|
|
2050
|
+
const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
2051
|
+
container.nativeElement.scrollTo(params);
|
|
2052
|
+
}
|
|
1944
2053
|
}
|
|
1945
2054
|
}
|
|
1946
2055
|
}
|
|
@@ -2028,7 +2137,7 @@ class NgVirtualListComponent {
|
|
|
2028
2137
|
}
|
|
2029
2138
|
}
|
|
2030
2139
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2031
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", stickyMap: "stickyMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", itemsOffset: "itemsOffset", trackBy: "trackBy", snappingMethod: "snappingMethod" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2140
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", stickyMap: "stickyMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", itemsOffset: "itemsOffset", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", trackBy: "trackBy", snappingMethod: "snappingMethod" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2032
2141
|
}
|
|
2033
2142
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgVirtualListComponent, decorators: [{
|
|
2034
2143
|
type: Component,
|
|
@@ -2070,6 +2179,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
2070
2179
|
type: Input
|
|
2071
2180
|
}], itemsOffset: [{
|
|
2072
2181
|
type: Input
|
|
2182
|
+
}], bufferSize: [{
|
|
2183
|
+
type: Input
|
|
2184
|
+
}], maxBufferSize: [{
|
|
2185
|
+
type: Input
|
|
2073
2186
|
}], trackBy: [{
|
|
2074
2187
|
type: Input
|
|
2075
2188
|
}], snappingMethod: [{
|