Angular 2 Kendo Grid拖拽滚动条时虚拟滚动分页失效问题
Hey, let's dig into why your Kendo Grid virtual scroll isn't loading the last page when you drag to the bottom. I've gone through your code and spotted several key issues that might be causing this:
1. 手动切片数据源干扰了虚拟滚动逻辑
In your pageChange method, you're doing this:
this.data = this.data.slice(this.contextData.PageNum < 3 ? 0 : (this.contextData.PageNum - 2) * this.pageSize, (this.contextData.PageNum * this.pageSize));
This is modifying the data array directly, which breaks Kendo's virtual scroll calculation. The grid relies on skip and pageSize to figure out which data range to display, not a sliced version of your accumulated data. Remove this line entirely—it's likely the biggest culprit here.
2. Dynamic pageSize is confusing the grid
You're switching pageSize between 100 (on initial load) and 50 (on subsequent scrolls):
if (this.currentSkip == 0) { // ... this.pageSize = 100; } else { this.pageSize = 50; }
Virtual scroll needs a consistent pageSize to calculate scroll positions correctly. Stick with 50 for all loads, including the initial one. This ensures the grid can accurately map scroll position to the correct skip value for the last page.
3. Accumulating data instead of loading only the needed range
You're pushing new data into the existing this.data array every time you load items:
this.data.push(passData);
For virtual scroll, you should replace the data array with only the current page's data, not accumulate all previous pages. When you scroll to the bottom, the grid expects to load exactly the 50 items for that last page, not add to a huge array of already loaded data. Update your ItemDataSource to clear the array before loading new data:
public ItemDataSource() { this.IsBusy = true; this.data = []; // Clear existing data first this.frameworkService.MaterialList(this.contextData).takeUntil(this.ngUnsubscribe).subscribe((data: any) => { this.items = data; for (let i = 0; i < this.items.MaterialList.length; i++) { // ... map your data as before this.data.push(passData); } this.previousSkip = this.currentSkip; this.loadItems(); }, (err) => { console.log(err); this.IsBusy = false; }); }
4. Incorrect page number calculation
You're relying on pageDataOutputDetail.PageNum to set contextData.PageNum, but you should calculate it directly from the pageChange event's skip value. The skip tells you exactly how many rows to skip, so the current page is:
const currentPage = (event.skip / this.pageSize) + 1; this.contextData.PageNum = currentPage;
This ensures you're always requesting the correct page that matches the scroll position, including the very last page (which would be 337154 / 50 ≈ 6743).
5. Simplify scroll direction logic
Your current logic for ScrollDirection is overcomplicating things. Since you're now calculating the page directly from skip, you might not even need the direction parameter—just pass the correct page number to your API, and let it return the right 50 items. If your API requires direction for caching or optimization, you can still calculate it from event.skip vs previousSkip, but make sure it's aligned with the actual page number.
Quick Fix Summary
- Remove the
data.slice()line inpageChange - Set
pageSize = 50once and keep it consistent - Clear
this.databefore loading new items inItemDataSource - Calculate
contextData.PageNumusingevent.skip / pageSize + 1 - Simplify scroll direction logic (or remove it if your API doesn't need it)
After making these changes, the grid should correctly calculate the last page's skip value when you scroll to the bottom and load the final 50 items.
内容的提问来源于stack exchange,提问作者Aarsh

