Angular 6中Telerik Kendo-Grid 4.8.4首次加载过慢问题:如何实现首次仅加载10条数据及分页时服务器端取数
Hey there! Let's sort out this performance issue with your Kendo Grid. Loading 20,000 records upfront is definitely going to cause that 20-second delay—we need to shift to proper server-side pagination so only the necessary data is fetched when needed. Here's how to adjust your Angular 6 + Kendo Grid 4.8.4 setup:
1. Set Up Initial State for Pagination
First, make sure your component's state initializes with the correct skip (starting index) and take (page size) values. This tells the grid to request only 10 records on first load:
import { State } from '@progress/kendo-data-query'; // In your component class public state: State = { skip: 0, // Start at the first record take: 10, // Load 10 records per page sort: [], filter: [], group: [] }; public totalRecords = 0; // Track total number of records from server public gridData$: Observable<any[]>; // Use Observable for async data loading
2. Update Grid Template for Server-Side Mode
Modify your grid template to:
- Bind to an observable data stream (using Angular's
asyncpipe) - Add the
[total]property to tell the grid how many total records exist (for pagination controls) - Keep your existing column definitions intact
<kendo-grid #grid="kendoGrid" class="k-grid-fullheight" (cellClick)="onCellClick($event)" (dataStateChange)="dataStateChange($event)" [sortable]="{allowUnsort: false, mode: 'single'}" [sort]="state.sort" [filter]="state.filter" [data]="gridData$ | async" <!-- Bind to observable with async pipe --> [selectable]="selectableSettings" [pageable]="true" [pageSize]="state.take" [skip]="state.skip" [total]="totalRecords" <!-- Critical for server-side pagination --> filterable="menu" [reorderable]="true" (selectionChange)="selectionChanged($event)" [groupable]="false" [group]="state.group" [columnMenu]="true" [resizable]="true"> <!-- Your existing column definitions stay here --> <kendo-grid-column showSelectAll="true" [width]="60" [minResizableWidth]="60"> <ng-template kendoGridHeaderTemplate let-column let-columnIndex="columnIndex"> <input type="checkbox" (click)="SetAllSelected($event)" /> </ng-template> <ng-template kendoGridCellTemplate let-dataItem> <input type="checkbox" [checked]="dataItem.selected" [disabled]="dataItem.Name !== null" <!-- Simplified disabled logic --> (click)="SetSelectedItem(dataItem)" /> </ng-template> </kendo-grid-column> <kendo-grid-column field="Name" [title]="NAME" filter="text" [filterable]="true" headerClass="kendoColumn"> <ng-template kendoGridCellTemplate let-dataItem> <a *ngIf="dataItem.Status === 0" [routerLink]="['/MyModule/details/', dataItem.Id]">{{dataItem.Name}}</a> <span *ngIf="dataItem.Status === 1">{{dataItem.Name}}</span> </ng-template> </kendo-grid-column> </kendo-grid>
3. Implement Data Loading with Server-Side Parameters
Create a method to fetch data from your server, passing the skip and take parameters from the grid state. This method will be triggered on initial load and every time the pagination/sort/filter state changes:
import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { of } from 'rxjs'; // In your component constructor constructor(private http: HttpClient) {} ngOnInit(): void { // Load initial data when component starts this.loadGridData(); } private loadGridData(): void { // Send skip/take to your server endpoint this.gridData$ = this.http.get<any>('/api/your-endpoint', { params: { skip: this.state.skip.toString(), take: this.state.take.toString() // Add sort/filter params here if you need server-side sorting/filtering too } }).pipe( switchMap(response => { // Store total records for pagination controls this.totalRecords = response.total; // Return the current page's data return of(response.data); }) ); } // Triggered when pagination/sort/filter changes public dataStateChange(newState: State): void { this.state = newState; this.loadGridData(); // Fetch new page data from server }
4. Ensure Your Server Endpoint Supports Pagination
Your backend API needs to:
- Accept
skipandtakeparameters - Return only the subset of records requested (e.g., skip=0, take=10 returns the first 10 records)
- Include the total number of records in the response (so the grid knows how many pages to render)
A sample server response might look like this:
{ "data": [/* 10 records matching the page request */], "total": 20000 }
Quick Note on "Select All" Logic
Since we're now using server-side pagination, the "select all" checkbox in your header will only affect the current page of data. If you need to select all 20,000 records, you'll need to add server-side logic to handle bulk selection (e.g., tracking selected IDs in your component or sending a bulk action request to the server).
内容的提问来源于stack exchange,提问作者CPK_2011

