You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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识别。解决步骤:

  1. 组件实现OnDestroy接口,销毁时取消dtTrigger订阅,避免内存泄漏。
  2. 在API数据加载完成的回调中调用this.dtTrigger.next(null),通知Datatable初始化或更新数据。
  3. 数据变更(如删除操作)后,通过重新创建dtTrigger并再次触发初始化来重新渲染Datatable。

内容的提问来源于stack exchange,提问作者Ishtiaq Ali Chughtai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:35:24