Angular Datatable从API加载数据时分页、搜索、排序失效及显示异常问题
Angular Datatable动态加载API数据后功能失效问题
问题现象
静态数据加载时,Angular Datatable的分页、搜索、排序功能正常;通过Node.js后端API加载数据后,这些功能全部失效,表格显示"No data available in table"提示,但数据已实际渲染在表格内。
相关代码
HTML代码
<table datatable [dtOptions]="dtOptions" class="datatable-init nowrap nk-tb-list nk-tb-ulist"> <thead> <tr class="nk-tb-item nk-tb-head"> <th class="nk-tb-col nk-tb-col-check"> <div class="custom-control custom-control-sm custom-checkbox notext"> <input type="checkbox" class="custom-control-input" id="uid" /> <label class="custom-control-label" for="uid"></label> </div> </th> <th class="nk-tb-col"><span class="sub-text">Customer Name</span></th> <th class="nk-tb-col tb-col-mb"> <span class="sub-text">Phone Number</span> </th> <th class="nk-tb-col tb-col-md"> <span class="sub-text">CNIC</span> </th> <th class="nk-tb-col tb-col-lg"> <span class="sub-text">Joining Date</span> </th> <th class="nk-tb-col tb-col-lg"> <span class="sub-text">Expiry Date</span> </th> <th class="nk-tb-col tb-col-lg"> <span class="sub-text">Status</span> </th> <th class="nk-tb-col nk-tb-col-tools text-end"></th> </tr> </thead> <tbody > <tr class="nk-tb-item" *ngFor="let user of allUsers"> <td class="nk-tb-col nk-tb-col-check"> <div class="custom-control custom-control-sm custom-checkbox notext"> <input type="checkbox" class="custom-control-input" id="uid1" /> <label class="custom-control-label" for="uid1"></label> </div> </td> <td class="nk-tb-col"> <span>{{user.customerName}}</span> </td> <td class="nk-tb-col tb-col-md"> <span>{{user.phoneNumber}}</span> </td> <td class="nk-tb-col tb-col-lg"> <span>{{user.CNIC_Number}}</span> </td> <td class="nk-tb-col tb-col-lg"> <span class="badge bg-secondary">{{user.Joining_Date}}</span> </td> <td class="nk-tb-col tb-col-md"> <span class="badge bg-danger">{{user.Expiry_Date}}</span> </td> <td class="nk-tb-col tb-col-md"> <span class="badge bg-success">Active</span> </td> <td class="nk-tb-col nk-tb-col-tools"> <ul class="nk-tb-actions gx-1"> <li> <div class="drodown"> <a href="#" class="dropdown-toggle btn btn-icon btn-trigger" data-bs-toggle="dropdown"><em class="icon ni ni-more-h"></em></a> <div class="dropdown-menu dropdown-menu-end"> <ul class="link-list-opt no-bdr"> <li> <a data-bs-toggle="modal" href="#mViewDetails"><em class="icon ni ni-eye"></em><span>View Details</span></a> </li> <li> <a data-bs-toggle="modal" href="#mEditDetails"><em class="icon ni ni-edit"></em><span>Edit Details</span></a> </li> <li> <a class="cursor" (click)="Toast.sendReminder()"><em class="icon ni ni-send"></em><span>Send Reminder</span></a> </li> <li> <a data-bs-toggle="modal" href="#mChangeStatus"><em class="icon ni ni-exchange"></em><span>Change Status</span></a> </li> <li> <a href=""><em class="icon ni ni-delete"></em><span>Delete User</span></a> </li> </ul> </div> </div> </li> </ul> </td> </tr> <!-- .nk-tb-item --> </tbody> </table>
TS代码
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Subject } from 'rxjs'; import { ToastService } from 'src/app/services/toast.service'; import { IDropdownSettings } from 'ng-multiselect-dropdown'; import { UserDetailService } from '../../services/user-detail.service'; import { Inter } from '../../inter'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-view-user', templateUrl: './view-user.component.html', styleUrls: ['./view-user.component.css'] }) export class ViewUserComponent implements OnInit, OnDestroy { constructor(public Toast: ToastService, private userDetails: UserDetailService, private http: HttpClient) { } dtOptions: DataTables.Settings = {}; dtTrigger: Subject<any> = new Subject<any>(); dropdownList: any = []; selectedItems = []; allUsers: Inter[] = []; dropdownSettings: IDropdownSettings = { singleSelection: false, idField: 'item_id', textField: 'item_text', selectAllText: 'Select All', unSelectAllText: 'UnSelect All', itemsShowLimit: 3, allowSearchFilter: true }; dataForTable: any; fetch() { this.http.get<any>('http://localhost:3000/user').subscribe(data => { this.dataForTable = data; console.log(this.dataForTable); }) } ngOnInit(): void { this.dtOptions = { pagingType: 'full_numbers', language: { searchPlaceholder: "Type Into Search" } }; this.fetch(); this.dropdownList = [ { item_id: 1, item_text: 'Naan Shami' }, { item_id: 2, item_text: 'Chicken Manchurian' }, { item_id: 3, item_text: 'Pune' }, { item_id: 4, item_text: 'Navsari' }, { item_id: 5, item_text: 'New Delhi' } ]; this.get() } get() { this.userDetails.get().subscribe((data) => { this.allUsers = data; // 数据加载完成后触发Datatable初始化 this.dtTrigger.next(null); }); } delete(id: number) { this.userDetails.delete(id).subscribe((data) => { this.allUsers = this.allUsers.filter((_) => _.id !== id); // 删除数据后重新渲染Datatable this.rerender(); }); } // 重新渲染Datatable方法 rerender(): void { this.dtTrigger.unsubscribe(); this.dtTrigger = new Subject<any>(); this.get(); } ngOnDestroy(): void { // 销毁组件时清理Subject,避免内存泄漏 this.dtTrigger.unsubscribe(); } }
users.module.ts代码
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { UsersRoutingModule } from './users-routing.module'; import { AddUserComponent } from './components/add-user/add-user.component'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ViewUserComponent } from './components/view-user/view-user.component'; import { DataTablesModule } from 'angular-datatables'; import { NgMultiSelectDropDownModule } from 'ng-multiselect-dropdown'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ AddUserComponent, ViewUserComponent ], imports: [ CommonModule, UsersRoutingModule, NgbModule, FormsModule, ReactiveFormsModule, DataTablesModule, HttpClientModule, NgMultiSelectDropDownModule.forRoot(), ] }) export class UsersModule { }
解决方案说明
问题核心是Angular Datatable初始化时,API请求尚未返回数据,Datatable检测不到数据就会显示空数据提示,而后续*ngFor渲染的数据未被Datatable识别。解决步骤:
- 组件实现
OnDestroy接口,销毁时取消dtTrigger订阅,避免内存泄漏。 - 在API数据加载完成的回调中调用
this.dtTrigger.next(null),通知Datatable初始化或更新数据。 - 数据变更(如删除操作)后,通过重新创建
dtTrigger并再次触发初始化来重新渲染Datatable。
内容的提问来源于stack exchange,提问作者Ishtiaq Ali Chughtai
相关产品推荐
相关产品推荐

