ng-virtual-list 19.7.29 → 19.7.30
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
CHANGED
|
@@ -639,8 +639,8 @@ Methods
|
|
|
639
639
|
|
|
640
640
|
| Method | Type | Description |
|
|
641
641
|
|--|--|--|
|
|
642
|
-
| scrollTo | (id: [Id](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/types/id.ts),
|
|
643
|
-
| scrollToEnd | (
|
|
642
|
+
| scrollTo | (id: [Id](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/types/id.ts), cb?: () => void, options?: [IScrollOptions](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/models/scroll-options.model.ts)) | The method scrolls the list to the element with the given `id` and returns the value of the scrolled area. |
|
|
643
|
+
| scrollToEnd | (cb?: () => void, options?: [IScrollOptions](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/models/scroll-options.model.ts)) | Scrolls the scroll area to the last item in the collection. |
|
|
644
644
|
| getItemBounds | (id: [Id](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/types/id.ts), behavior?: ScrollBehavior) => void | Returns the bounds of an element with a given id |
|
|
645
645
|
| focus | [Id](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/types/id.ts), align: [FocusAlignment](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/types/focus-alignment.ts) = [FocusAlignments.NONE](https://github.com/DjonnyX/ng-virtual-list/blob/19.x/projects/ng-virtual-list/src/lib/enums/focus-alignments.ts) | Focus an list item by a given id. |
|
|
646
646
|
|
|
@@ -4,7 +4,7 @@ import * as i0 from '@angular/core';
|
|
|
4
4
|
import { Injectable, inject, signal, ElementRef, ChangeDetectionStrategy, Component, viewChild, output, input, ViewContainerRef, ViewChild, ViewEncapsulation } from '@angular/core';
|
|
5
5
|
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
|
6
6
|
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
|
7
|
-
import { Subject, tap, fromEvent, combineLatest, map, filter, distinctUntilChanged, debounceTime, switchMap, of } from 'rxjs';
|
|
7
|
+
import { Subject, tap, fromEvent, combineLatest, map, filter, distinctUntilChanged, debounceTime, switchMap, of, BehaviorSubject as BehaviorSubject$1, delay, take } from 'rxjs';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Action modes for collection elements.
|
|
@@ -2728,14 +2728,6 @@ class NgVirtualListComponent {
|
|
|
2728
2728
|
this.updateRegularRenderer();
|
|
2729
2729
|
}
|
|
2730
2730
|
};
|
|
2731
|
-
_onScrollHandler = (e) => {
|
|
2732
|
-
this.clearScrollToRepeatExecutionTimeout();
|
|
2733
|
-
const container = this._container()?.nativeElement;
|
|
2734
|
-
if (container) {
|
|
2735
|
-
const scrollSize = (this._isVertical ? container.scrollTop : container.scrollLeft), actualScrollSize = scrollSize;
|
|
2736
|
-
this._scrollSize.set(actualScrollSize);
|
|
2737
|
-
}
|
|
2738
|
-
};
|
|
2739
2731
|
itemToFocus = (element, position, align = FocusAlignments.CENTER) => {
|
|
2740
2732
|
const container = this._container()?.nativeElement;
|
|
2741
2733
|
if (container) {
|
|
@@ -2785,6 +2777,17 @@ class NgVirtualListComponent {
|
|
|
2785
2777
|
};
|
|
2786
2778
|
_cacheVersion = signal(-1);
|
|
2787
2779
|
_isResetedReachStart = true;
|
|
2780
|
+
_$scrollTo = new Subject();
|
|
2781
|
+
$scrollTo = this._$scrollTo.asObservable();
|
|
2782
|
+
_$scrollToCanceller = new Subject();
|
|
2783
|
+
cancelScrollTo() {
|
|
2784
|
+
if (this._$scrollToCanceller) {
|
|
2785
|
+
this._$scrollToCanceller.next();
|
|
2786
|
+
this._$scrollToCanceller.complete();
|
|
2787
|
+
this._$scrollToCanceller = undefined;
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
;
|
|
2788
2791
|
_onTrackBoxResetHandler = (v) => {
|
|
2789
2792
|
if (v) {
|
|
2790
2793
|
this._isResetedReachStart = true;
|
|
@@ -2836,7 +2839,7 @@ class NgVirtualListComponent {
|
|
|
2836
2839
|
this._trackBox.trackingPropertyName = v;
|
|
2837
2840
|
})).subscribe();
|
|
2838
2841
|
const $bounds = toObservable(this._bounds).pipe(filter(b => !!b)), $items = toObservable(this.items).pipe(map(i => !i ? [] : i)), $scrollSize = toObservable(this._scrollSize), $itemSize = toObservable(this.itemSize).pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $itemConfigMap = toObservable(this.itemConfigMap).pipe(map(v => !v ? {} : v)), $snap = toObservable(this.snap), $isVertical = toObservable(this.direction).pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $isLazy = toObservable(this.collectionMode).pipe(map(v => this.getIsLazy(v || DEFAULT_COLLECTION_MODE))), $dynamicSize = toObservable(this.dynamicSize), $enabledBufferOptimization = toObservable(this.enabledBufferOptimization), $snappingMethod = toObservable(this.snappingMethod).pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $methodForSelecting = toObservable(this.methodForSelecting), $selectedIds = toObservable(this.selectedIds), $collapsedIds = toObservable(this.collapsedIds).pipe(map(v => Array.isArray(v) ? v : [])), $collapsedItemIds = toObservable(this._collapsedItemIds).pipe(map(v => Array.isArray(v) ? v : [])), $actualItems = toObservable(this._actualItems), $screenReaderMessage = toObservable(this.screenReaderMessage), $displayItems = this._service.$displayItems, $cacheVersion = toObservable(this._cacheVersion);
|
|
2839
|
-
combineLatest([$displayItems, $screenReaderMessage, $isVertical, $scrollSize, $bounds]).pipe(takeUntilDestroyed(), distinctUntilChanged(), debounceTime(100), tap(([items, screenReaderMessage, isVertical, scrollSize, bounds]) => {
|
|
2842
|
+
combineLatest([$displayItems, $screenReaderMessage, $isVertical, $scrollSize, $bounds]).pipe(takeUntilDestroyed(), distinctUntilChanged(), debounceTime(100), takeUntilDestroyed(), tap(([items, screenReaderMessage, isVertical, scrollSize, bounds]) => {
|
|
2840
2843
|
this.screenReaderFormattedMessage.set(formatScreenReaderMessage(items, screenReaderMessage, scrollSize, isVertical, bounds));
|
|
2841
2844
|
})).subscribe();
|
|
2842
2845
|
$isLazy.pipe(takeUntilDestroyed(), tap(v => {
|
|
@@ -2942,6 +2945,137 @@ class NgVirtualListComponent {
|
|
|
2942
2945
|
}
|
|
2943
2946
|
return of(displayItems);
|
|
2944
2947
|
})).subscribe();
|
|
2948
|
+
const $container = toObservable(this._container);
|
|
2949
|
+
$container.pipe(distinctUntilChanged(), filter(v => !!v), map(v => v.nativeElement), switchMap(container => {
|
|
2950
|
+
return fromEvent(container, SCROLL);
|
|
2951
|
+
}), tap(e => {
|
|
2952
|
+
const containerEl = this._container();
|
|
2953
|
+
if (containerEl) {
|
|
2954
|
+
const scrollSize = (this._isVertical ? containerEl.nativeElement.scrollTop : containerEl.nativeElement.scrollLeft), currentScollSize = this._scrollSize();
|
|
2955
|
+
this._trackBox.deltaDirection = currentScollSize > scrollSize ? -1 : currentScollSize < scrollSize ? 1 : 0;
|
|
2956
|
+
const event = new ScrollEvent({
|
|
2957
|
+
direction: this._trackBox.scrollDirection, container: containerEl.nativeElement,
|
|
2958
|
+
list: this._list().nativeElement, delta: this._trackBox.delta,
|
|
2959
|
+
scrollDelta: this._trackBox.scrollDelta, isVertical: this._isVertical,
|
|
2960
|
+
});
|
|
2961
|
+
this.onScroll.emit(event);
|
|
2962
|
+
}
|
|
2963
|
+
})).subscribe();
|
|
2964
|
+
$container.pipe(distinctUntilChanged(), filter(v => !!v), map(v => v.nativeElement), switchMap(container => {
|
|
2965
|
+
return fromEvent(container, SCROLL_END);
|
|
2966
|
+
}), tap(e => {
|
|
2967
|
+
const containerEl = this._container();
|
|
2968
|
+
if (containerEl) {
|
|
2969
|
+
const scrollSize = (this._isVertical ? containerEl.nativeElement.scrollTop : containerEl.nativeElement.scrollLeft), currentScollSize = this._scrollSize();
|
|
2970
|
+
this._trackBox.deltaDirection = currentScollSize > scrollSize ? -1 : 0;
|
|
2971
|
+
const event = new ScrollEvent({
|
|
2972
|
+
direction: this._trackBox.scrollDirection, container: containerEl.nativeElement,
|
|
2973
|
+
list: this._list().nativeElement, delta: this._trackBox.delta,
|
|
2974
|
+
scrollDelta: this._trackBox.scrollDelta, isVertical: this._isVertical,
|
|
2975
|
+
});
|
|
2976
|
+
this.onScrollEnd.emit(event);
|
|
2977
|
+
}
|
|
2978
|
+
})).subscribe();
|
|
2979
|
+
const _$scrollCanceller = new BehaviorSubject$1(false);
|
|
2980
|
+
$container.pipe(distinctUntilChanged(), filter(v => !!v), map(v => v.nativeElement), switchMap(container => {
|
|
2981
|
+
return fromEvent(container, SCROLL).pipe(filter(() => !_$scrollCanceller.getValue()));
|
|
2982
|
+
}), tap(e => {
|
|
2983
|
+
this.cancelScrollTo();
|
|
2984
|
+
const container = this._container()?.nativeElement;
|
|
2985
|
+
if (container) {
|
|
2986
|
+
const scrollSize = (this._isVertical ? container.scrollTop : container.scrollLeft), actualScrollSize = scrollSize;
|
|
2987
|
+
this._scrollSize.set(actualScrollSize);
|
|
2988
|
+
}
|
|
2989
|
+
})).subscribe();
|
|
2990
|
+
$container.pipe(distinctUntilChanged(), filter(v => !!v), map(v => v.nativeElement), tap(container => {
|
|
2991
|
+
if (this._resizeObserver) {
|
|
2992
|
+
this._resizeObserver.disconnect();
|
|
2993
|
+
}
|
|
2994
|
+
this._resizeObserver = new ResizeObserver(this._onResizeHandler);
|
|
2995
|
+
this._resizeObserver.observe(container);
|
|
2996
|
+
this._onResizeHandler();
|
|
2997
|
+
})).subscribe();
|
|
2998
|
+
const $scrollTo = this.$scrollTo;
|
|
2999
|
+
combineLatest([$container, $scrollTo]).pipe(takeUntilDestroyed(), filter(([container]) => container !== undefined), map(([container, event]) => ({ container: container?.nativeElement, event })), switchMap(({ container, event }) => {
|
|
3000
|
+
const cnt = container, { id, behavior = BEHAVIOR_INSTANT, iteration = 0, isLastIteration = false, scrollCalled = false, cb } = event;
|
|
3001
|
+
const items = this._actualItems();
|
|
3002
|
+
if (items && items.length) {
|
|
3003
|
+
const dynamicSize = this.dynamicSize(), itemSize = this.itemSize();
|
|
3004
|
+
this.cancelScrollTo();
|
|
3005
|
+
if (dynamicSize) {
|
|
3006
|
+
_$scrollCanceller.next(true);
|
|
3007
|
+
const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), items = this._actualItems(), isVertical = this._isVertical, currentScollSize = (isVertical ? cnt.scrollTop : cnt.scrollLeft), delta = this._trackBox.delta, opts = {
|
|
3008
|
+
bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
|
|
3009
|
+
bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(),
|
|
3010
|
+
scrollSize: (isVertical ? cnt.scrollTop : cnt.scrollLeft) + delta,
|
|
3011
|
+
snap: this.snap(), fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization(),
|
|
3012
|
+
}, scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior: BEHAVIOR_INSTANT };
|
|
3013
|
+
if (scrollSize === -1) {
|
|
3014
|
+
_$scrollCanceller.next(false);
|
|
3015
|
+
return of([true, { id, container: cnt, scrollCalled, cb }]);
|
|
3016
|
+
}
|
|
3017
|
+
this._trackBox.clearDelta();
|
|
3018
|
+
const { displayItems, totalSize } = this._trackBox.updateCollection(items, itemConfigMap, {
|
|
3019
|
+
...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
|
|
3020
|
+
}), delta1 = this._trackBox.delta;
|
|
3021
|
+
this._service.collection = displayItems;
|
|
3022
|
+
this._trackBox.clearDelta();
|
|
3023
|
+
let actualScrollSize = scrollSize + delta1;
|
|
3024
|
+
this.resetBoundsSize(isVertical, totalSize);
|
|
3025
|
+
this.createDisplayComponentsIfNeed(displayItems);
|
|
3026
|
+
this.tracking();
|
|
3027
|
+
const _scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
|
|
3028
|
+
if (_scrollSize === -1) {
|
|
3029
|
+
_$scrollCanceller.next(false);
|
|
3030
|
+
return of([true, { id, container: cnt, scrollCalled, cb }]);
|
|
3031
|
+
}
|
|
3032
|
+
const notChanged = actualScrollSize === currentScollSize;
|
|
3033
|
+
cnt.scrollTo(params);
|
|
3034
|
+
if ((!notChanged && iteration < MAX_SCROLL_TO_ITERATIONS) || iteration < MAX_SCROLL_TO_ITERATIONS) {
|
|
3035
|
+
this.cancelScrollTo();
|
|
3036
|
+
this._$scrollToCanceller = new Subject();
|
|
3037
|
+
this._$scrollTo.next(params);
|
|
3038
|
+
return of([false, {
|
|
3039
|
+
id, behavior: BEHAVIOR_INSTANT, container: cnt, iteration: iteration + 1,
|
|
3040
|
+
isLastIteration: notChanged, scrollCalled: true, cb,
|
|
3041
|
+
}]).pipe(delay(1));
|
|
3042
|
+
}
|
|
3043
|
+
else {
|
|
3044
|
+
this._scrollSize.set(actualScrollSize);
|
|
3045
|
+
_$scrollCanceller.next(false);
|
|
3046
|
+
return of([true, { id, container: cnt, scrollCalled, cb }]);
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
else {
|
|
3050
|
+
const index = items.findIndex(item => item.id === id);
|
|
3051
|
+
if (index > -1) {
|
|
3052
|
+
const isVertical = this._isVertical, currentScollSize = (isVertical ? cnt.scrollTop : cnt.scrollLeft), scrollSize = index * this.itemSize();
|
|
3053
|
+
if (currentScollSize !== scrollSize) {
|
|
3054
|
+
const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
3055
|
+
cnt.scrollTo(params);
|
|
3056
|
+
return fromEvent(cnt, SCROLL_END).pipe(take(1), switchMap(() => of([true, { id, container: cnt, cb }])));
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
return of([true, { id, container: cnt, cb }]);
|
|
3062
|
+
}), filter(params => !!params), takeUntilDestroyed(), tap(([finished, params]) => {
|
|
3063
|
+
if (!finished) {
|
|
3064
|
+
if (params) {
|
|
3065
|
+
this._$scrollTo.next(params);
|
|
3066
|
+
}
|
|
3067
|
+
return;
|
|
3068
|
+
}
|
|
3069
|
+
const p = params;
|
|
3070
|
+
if (p.scrollCalled && p.container) {
|
|
3071
|
+
p.cb?.();
|
|
3072
|
+
return;
|
|
3073
|
+
}
|
|
3074
|
+
if (p) {
|
|
3075
|
+
const { cb } = p;
|
|
3076
|
+
cb?.();
|
|
3077
|
+
}
|
|
3078
|
+
})).subscribe();
|
|
2945
3079
|
const $itemRenderer = toObservable(this.itemRenderer);
|
|
2946
3080
|
$itemRenderer.pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(v => !!v), tap(v => {
|
|
2947
3081
|
this._itemRenderer.set(v);
|
|
@@ -3106,137 +3240,31 @@ class NgVirtualListComponent {
|
|
|
3106
3240
|
}
|
|
3107
3241
|
}
|
|
3108
3242
|
/**
|
|
3109
|
-
* The method scrolls the list to the element with the given id and returns the value of the scrolled area.
|
|
3110
|
-
* Behavior accepts the values "auto", "instant" and "smooth".
|
|
3243
|
+
* The method scrolls the list to the element with the given `id` and returns the value of the scrolled area.
|
|
3111
3244
|
*/
|
|
3112
|
-
scrollTo(id,
|
|
3245
|
+
scrollTo(id, cb, options) {
|
|
3246
|
+
const behavior = options?.behavior ?? BEHAVIOR_INSTANT, iteration = options?.iteration ?? 0;
|
|
3113
3247
|
validateId(id);
|
|
3114
3248
|
validateScrollBehavior(behavior);
|
|
3115
3249
|
validateIteration(iteration);
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
_scrollToRepeatExecutionTimeout;
|
|
3119
|
-
clearScrollToRepeatExecutionTimeout() {
|
|
3120
|
-
clearTimeout(this._scrollToRepeatExecutionTimeout);
|
|
3121
|
-
}
|
|
3122
|
-
scrollToExecutor(id, behavior, iteration = 0, isLastIteration = false) {
|
|
3123
|
-
const items = this._actualItems();
|
|
3124
|
-
if (!items || !items.length) {
|
|
3125
|
-
return;
|
|
3126
|
-
}
|
|
3127
|
-
const dynamicSize = this.dynamicSize(), container = this._container(), itemSize = this.itemSize();
|
|
3128
|
-
if (container) {
|
|
3129
|
-
this.clearScrollToRepeatExecutionTimeout();
|
|
3130
|
-
if (dynamicSize) {
|
|
3131
|
-
if (container) {
|
|
3132
|
-
container.nativeElement.removeEventListener(SCROLL, this._onScrollHandler);
|
|
3133
|
-
}
|
|
3134
|
-
const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, itemConfigMap = this.itemConfigMap(), items = this._actualItems(), isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
|
|
3135
|
-
bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
|
|
3136
|
-
bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(),
|
|
3137
|
-
scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
|
|
3138
|
-
snap: this.snap(), fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization(),
|
|
3139
|
-
}, scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
3140
|
-
if (scrollSize === -1) {
|
|
3141
|
-
container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
3142
|
-
return;
|
|
3143
|
-
}
|
|
3144
|
-
this._trackBox.clearDelta();
|
|
3145
|
-
if (container) {
|
|
3146
|
-
const { displayItems, totalSize } = this._trackBox.updateCollection(items, itemConfigMap, {
|
|
3147
|
-
...opts, scrollSize, fromItemId: isLastIteration ? undefined : id,
|
|
3148
|
-
}), delta = this._trackBox.delta;
|
|
3149
|
-
this._service.collection = displayItems;
|
|
3150
|
-
this._trackBox.clearDelta();
|
|
3151
|
-
let actualScrollSize = scrollSize + delta;
|
|
3152
|
-
this.resetBoundsSize(isVertical, totalSize);
|
|
3153
|
-
this.createDisplayComponentsIfNeed(displayItems);
|
|
3154
|
-
this.tracking();
|
|
3155
|
-
const _scrollSize = this._trackBox.getItemPosition(id, itemConfigMap, { ...opts, scrollSize: actualScrollSize, fromItemId: id });
|
|
3156
|
-
if (_scrollSize === -1) {
|
|
3157
|
-
container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
3158
|
-
return;
|
|
3159
|
-
}
|
|
3160
|
-
const notChanged = actualScrollSize === _scrollSize;
|
|
3161
|
-
if (!notChanged || iteration < MAX_SCROLL_TO_ITERATIONS) {
|
|
3162
|
-
this.clearScrollToRepeatExecutionTimeout();
|
|
3163
|
-
this._scrollToRepeatExecutionTimeout = setTimeout(() => {
|
|
3164
|
-
this.scrollToExecutor(id, BEHAVIOR_INSTANT, iteration + 1, notChanged);
|
|
3165
|
-
});
|
|
3166
|
-
}
|
|
3167
|
-
else {
|
|
3168
|
-
this._scrollSize.set(actualScrollSize);
|
|
3169
|
-
container.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
3170
|
-
}
|
|
3171
|
-
}
|
|
3172
|
-
container.nativeElement.scrollTo(params);
|
|
3173
|
-
this._scrollSize.set(scrollSize);
|
|
3174
|
-
}
|
|
3175
|
-
else {
|
|
3176
|
-
const index = items.findIndex(item => item.id === id);
|
|
3177
|
-
if (index > -1) {
|
|
3178
|
-
const scrollSize = index * this.itemSize();
|
|
3179
|
-
const params = { [this._isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
3180
|
-
container.nativeElement.scrollTo(params);
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
}
|
|
3250
|
+
const actualIteration = validateScrollIteration(iteration);
|
|
3251
|
+
this._$scrollTo.next({ id, behavior, iteration: actualIteration, isLastIteration: actualIteration === MAX_SCROLL_TO_ITERATIONS, cb });
|
|
3184
3252
|
}
|
|
3185
3253
|
/**
|
|
3186
|
-
* Scrolls the scroll area to the
|
|
3254
|
+
* Scrolls the scroll area to the last item in the collection.
|
|
3187
3255
|
*/
|
|
3188
|
-
scrollToEnd(
|
|
3256
|
+
scrollToEnd(cb, options) {
|
|
3257
|
+
const behavior = options?.behavior ?? BEHAVIOR_INSTANT, iteration = options?.iteration ?? 0;
|
|
3189
3258
|
validateScrollBehavior(behavior);
|
|
3190
3259
|
validateIteration(iteration);
|
|
3191
|
-
const items = this.items(), latItem = items[items.length > 0 ? items.length - 1 : 0];
|
|
3192
|
-
this.scrollTo(
|
|
3193
|
-
}
|
|
3194
|
-
_onContainerScrollHandler = (e) => {
|
|
3195
|
-
const containerEl = this._container();
|
|
3196
|
-
if (containerEl) {
|
|
3197
|
-
const scrollSize = (this._isVertical ? containerEl.nativeElement.scrollTop : containerEl.nativeElement.scrollLeft), currentScollSize = this._scrollSize();
|
|
3198
|
-
this._trackBox.deltaDirection = currentScollSize > scrollSize ? -1 : currentScollSize < scrollSize ? 1 : 0;
|
|
3199
|
-
const event = new ScrollEvent({
|
|
3200
|
-
direction: this._trackBox.scrollDirection, container: containerEl.nativeElement,
|
|
3201
|
-
list: this._list().nativeElement, delta: this._trackBox.delta,
|
|
3202
|
-
scrollDelta: this._trackBox.scrollDelta, isVertical: this._isVertical,
|
|
3203
|
-
});
|
|
3204
|
-
this.onScroll.emit(event);
|
|
3205
|
-
}
|
|
3206
|
-
};
|
|
3207
|
-
_onContainerScrollEndHandler = (e) => {
|
|
3208
|
-
const containerEl = this._container();
|
|
3209
|
-
if (containerEl) {
|
|
3210
|
-
const scrollSize = (this._isVertical ? containerEl.nativeElement.scrollTop : containerEl.nativeElement.scrollLeft), currentScollSize = this._scrollSize();
|
|
3211
|
-
this._trackBox.deltaDirection = currentScollSize > scrollSize ? -1 : 0;
|
|
3212
|
-
const event = new ScrollEvent({
|
|
3213
|
-
direction: this._trackBox.scrollDirection, container: containerEl.nativeElement,
|
|
3214
|
-
list: this._list().nativeElement, delta: this._trackBox.delta,
|
|
3215
|
-
scrollDelta: this._trackBox.scrollDelta, isVertical: this._isVertical,
|
|
3216
|
-
});
|
|
3217
|
-
this.onScrollEnd.emit(event);
|
|
3218
|
-
}
|
|
3219
|
-
};
|
|
3220
|
-
ngAfterViewInit() {
|
|
3221
|
-
this.afterViewInit();
|
|
3222
|
-
}
|
|
3223
|
-
afterViewInit() {
|
|
3224
|
-
const containerEl = this._container();
|
|
3225
|
-
if (containerEl) {
|
|
3226
|
-
// for direction calculation
|
|
3227
|
-
containerEl.nativeElement.addEventListener(SCROLL, this._onContainerScrollHandler);
|
|
3228
|
-
containerEl.nativeElement.addEventListener(SCROLL_END, this._onContainerScrollEndHandler);
|
|
3229
|
-
containerEl.nativeElement.addEventListener(SCROLL, this._onScrollHandler);
|
|
3230
|
-
this._resizeObserver = new ResizeObserver(this._onResizeHandler);
|
|
3231
|
-
this._resizeObserver.observe(containerEl.nativeElement);
|
|
3232
|
-
this._onResizeHandler();
|
|
3233
|
-
}
|
|
3260
|
+
const items = this.items(), latItem = items[items.length > 0 ? items.length - 1 : 0], id = latItem.id, actualIteration = validateScrollIteration(iteration);
|
|
3261
|
+
this._$scrollTo.next({ id, behavior, iteration: actualIteration, isLastIteration: actualIteration === MAX_SCROLL_TO_ITERATIONS, cb });
|
|
3234
3262
|
}
|
|
3235
3263
|
ngOnDestroy() {
|
|
3236
3264
|
this.dispose();
|
|
3237
3265
|
}
|
|
3238
3266
|
dispose() {
|
|
3239
|
-
this.
|
|
3267
|
+
this.cancelScrollTo();
|
|
3240
3268
|
if (this._trackBox) {
|
|
3241
3269
|
this._trackBox.dispose();
|
|
3242
3270
|
}
|
|
@@ -3249,12 +3277,6 @@ class NgVirtualListComponent {
|
|
|
3249
3277
|
if (this._resizeObserver) {
|
|
3250
3278
|
this._resizeObserver.disconnect();
|
|
3251
3279
|
}
|
|
3252
|
-
const containerEl = this._container();
|
|
3253
|
-
if (containerEl) {
|
|
3254
|
-
containerEl.nativeElement.removeEventListener(SCROLL, this._onScrollHandler);
|
|
3255
|
-
containerEl.nativeElement.removeEventListener(SCROLL, this._onContainerScrollHandler);
|
|
3256
|
-
containerEl.nativeElement.removeEventListener(SCROLL_END, this._onContainerScrollEndHandler);
|
|
3257
|
-
}
|
|
3258
3280
|
if (this._snapedDisplayComponent) {
|
|
3259
3281
|
this._snapedDisplayComponent.destroy();
|
|
3260
3282
|
}
|