@progress/kendo-angular-treelist
Version:
Kendo UI TreeList for Angular - Display hierarchical data in an Angular tree grid view that supports sorting, filtering, paging, and much more.
81 lines (80 loc) • 3.66 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Injectable, NgZone } from '@angular/core';
import { Subscription, Subject, fromEvent } from 'rxjs';
import { distinctUntilChanged, filter, map, tap } from 'rxjs/operators';
import * as i0 from "@angular/core";
/**
* @hidden
*/
export class ScrollSyncService {
ngZone;
changes = new Subject();
elements = [];
source;
subscriptions = new Subscription();
headerSubscription = new Subscription();
bodySubscription = new Subscription();
constructor(ngZone) {
this.ngZone = ngZone;
this.subscriptions.add(this.changes.subscribe(args => this.scrollLeft(args)));
}
registerEmitter(el, sourceType) {
this.unregister(sourceType);
this.elements.push({ element: el, sourceType });
if (sourceType === "body" || sourceType === "header") {
this.ngZone.runOutsideAngular(() => {
const obs = fromEvent(el, "scroll").pipe(map(({ target: { scrollLeft } }) => ({
scrollLeft,
sourceType
})));
const subscription = obs.pipe(distinctUntilChanged((x, y) => (x.scrollLeft === y.scrollLeft)), filter(x => !this.source || this.source === x.sourceType), tap(x => this.source = x.sourceType))
.subscribe((x) => this.changes.next(x));
subscription.add(obs.pipe(filter(x => this.source && this.source !== x.sourceType))
.subscribe(() => this.source = undefined));
if (sourceType === "body") {
this.bodySubscription.add(subscription);
}
else {
this.headerSubscription.add(subscription);
}
});
}
}
/**
* destroy
*/
destroy() {
this.subscriptions.unsubscribe();
this.headerSubscription.unsubscribe();
this.bodySubscription.unsubscribe();
}
scrollLeft({ scrollLeft, sourceType }) {
this.ngZone.runOutsideAngular(() => {
this.elements
.filter(x => sourceType !== x.sourceType)
.forEach(({ element }) => element.scrollLeft = scrollLeft);
});
}
unregister(sourceType) {
const index = this.elements.findIndex(x => x.sourceType === sourceType);
if (index > -1) {
if (sourceType === "header") {
this.headerSubscription.unsubscribe();
this.headerSubscription = new Subscription();
}
else if (sourceType === "body") {
this.bodySubscription.unsubscribe();
this.bodySubscription = new Subscription();
}
this.elements.splice(index, 1);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollSyncService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollSyncService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScrollSyncService, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i0.NgZone }]; } });