Hostlistener滚动事件未触发,SyncFusion ejTreeGrid滚动加载数据问题
Got it, let's fix this issue where HostListener doesn't pick up scroll events from ejTreeGrid—since it uses a custom scrolling implementation, native browser scroll listeners won't work. Here are a couple of proven approaches to capture the scrollTop offset and trigger your data fetch requests:
1. Listen Directly to the TreeGrid's Scroll Container Event
The ejTreeGrid wraps its scrollable content in an internal container, and this container still fires standard scroll events. You can grab the grid's element and attach a listener to it:
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; import { TreeGridComponent } from '@syncfusion/ej2-angular-treegrid'; @Component({ selector: 'app-tree-grid-container', templateUrl: './tree-grid-container.component.html' }) export class TreeGridContainerComponent implements OnInit, OnDestroy { @ViewChild('treegrid') treeGrid?: TreeGridComponent; private scrollListener?: (event: Event) => void; ngOnInit(): void { if (this.treeGrid) { // Bind the scroll listener to the grid's internal scroll container this.scrollListener = this.handleTreeGridScroll.bind(this); this.treeGrid.element.addEventListener('scroll', this.scrollListener); } } private handleTreeGridScroll(event: Event): void { const scrollContainer = event.target as HTMLElement; const currentScrollTop = scrollContainer.scrollTop; console.log('Current scroll offset:', currentScrollTop); // Calculate your take/skip/page parameters based on scroll position const pageSize = 25; // Adjust to your configured page size const currentPage = Math.floor(currentScrollTop / (scrollContainer.clientHeight)) + 1; const skip = (currentPage - 1) * pageSize; const take = pageSize; // Trigger your HTTP GET request with updated parameters this.fetchGridData(take, skip); } private fetchGridData(take: number, skip: number): void { // Replace with your actual API call logic // this.dataService.getItems(take, skip).subscribe(data => { // this.treeGrid!.dataSource = data; // }); } ngOnDestroy(): void { // Clean up the listener to avoid memory leaks if (this.treeGrid && this.scrollListener) { this.treeGrid.element.removeEventListener('scroll', this.scrollListener); } } }
Why this works:
Even though ejTreeGrid uses custom scrolling logic, its internal scrollable element still emits standard scroll events. Attaching the listener directly to this element lets you capture the scrollTop value reliably.
2. Fallback: Use MutationObserver to Track ScrollTop Changes
If for some reason the scroll event doesn't fire (unlikely, but possible in older versions), you can use a MutationObserver to watch for changes to the scroll container's style attributes (since custom scroll often updates scrollTop via inline styles):
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; import { TreeGridComponent } from '@syncfusion/ej2-angular-treegrid'; @Component({ selector: 'app-tree-grid-container', templateUrl: './tree-grid-container.component.html' }) export class TreeGridContainerComponent implements OnInit, OnDestroy { @ViewChild('treegrid') treeGrid?: TreeGridComponent; private scrollObserver?: MutationObserver; ngOnInit(): void { if (this.treeGrid) { const scrollContainer = this.treeGrid.element.querySelector('.e-content') as HTMLElement; if (scrollContainer) { this.scrollObserver = new MutationObserver(mutations => { mutations.forEach(mutation => { if (mutation.attributeName === 'style') { const currentScrollTop = scrollContainer.scrollTop; this.updateFetchParameters(currentScrollTop); } }); }); // Observe changes to the container's style attribute this.scrollObserver.observe(scrollContainer, { attributes: true }); } } } private updateFetchParameters(scrollTop: number): void { // Same calculation logic as above to get take/skip/page const pageSize = 25; const currentPage = Math.floor(scrollTop / (document.querySelector('.e-content')!.clientHeight)) + 1; const skip = (currentPage - 1) * pageSize; const take = pageSize; this.fetchGridData(take, skip); } private fetchGridData(take: number, skip: number): void { // Your API call here } ngOnDestroy(): void { if (this.scrollObserver) { this.scrollObserver.disconnect(); } } }
Key Notes:
- Always clean up event listeners/observers in
ngOnDestroyto prevent memory leaks. - Adjust
pageSizeto match your TreeGrid's configuration for accurate page calculations. - If you're using server-side pagination with Syncfusion's built-in support, you can also hook into the
queryevent to modifytake/skipparameters dynamically, but the above methods give you direct control over scroll-triggered requests.
内容的提问来源于stack exchange,提问作者Julius Dzidzevičius

