带有 Angular-Datatables 的 Angular 17:无法重新渲染数据表

问题描述 投票:0回答:1

我正在使用 Angular-Datatables 开发 Angular 17 应用程序,并且在搜索后更新数据时重新渲染 DataTable 时遇到问题。以下是我的组件的相关代码:

html

<div class="search-container">
  <input type="text" [(ngModel)]="searchTerm" placeholder="Search by title" />
  <button (click)="searchPosts()">Search</button>
</div>

<table datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover">
  <thead>
    <tr>
      <th>ID</th>
      <th>Title</th>
      <th>Body</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let post of posts">
      <td>{{ post.id }}</td>
      <td>{{ post.title }}</td>
      <td>{{ post.body }}</td>
    </tr>
  </tbody>
</table>

Ts 文件

import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-data-table',
  templateUrl: './data-table.component.html',
  styleUrls: ['./data-table.component.css']
})
export class DataTableComponent implements OnInit, OnDestroy {
  dtOptions: DataTables.Settings = {};
  dtTrigger: Subject<any> = new Subject<any>();
  posts: any[] = [];
  searchTerm: string = '';

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.dtOptions = {
      pagingType: 'full_numbers',
      pageLength: 10,
      destroy: true
    };

    // Fetch initial data
    this.fetchData();
  }

  fetchData(): void {
    this.http.get('https://jsonplaceholder.typicode.com/posts')
      .subscribe((posts: any[]) => {
        this.posts = posts;
        this.dtTrigger.next(null);
      });
  }

  searchPosts(): void {
    if (this.searchTerm.trim() === '') {
      this.fetchData(); // If search term is empty, fetch all data
    } else {
      this.http.get(`https://jsonplaceholder.typicode.com/posts?title_like=${this.searchTerm}`)
        .subscribe((posts: any[]) => {
          this.posts = posts;
          this.dtTrigger.next(null); // Re-render the DataTable
        });
    }
  }

  ngOnDestroy(): void {
    this.dtTrigger.unsubscribe();
  }
}

问题: 执行搜索时,我无法使用更新的数据重新呈现数据表。我查阅了文档并尝试了各种方法,包括在 ngAfterViewInit 中触发 dtTrigger,但没有成功。

文档链接:https://l-lin.github.io/angular-datatables/#/basic/with-ajax

我还尝试实现这样的重新渲染方法:

rerender() {
  this.dtElement.dtInstance.then(dtInstance => {
    dtInstance.destroy();
    this.dtTrigger.next(null);
  });
}

注意: 我正在使用 Angular 17 和最新版本的 Angular-Datatables。任何帮助或建议将不胜感激!

angular angularjs datatable datatables angular17
1个回答
0
投票

要在更新 Angular-Datatables 中的数据后正确重新渲染 DataTable,您需要确保正确处理 DataTable 实例的生命周期。以下是解决该问题的详细方法:

  1. 修改 TypeScript 文件以使用 @ViewChild 并实现重新渲染方法
  2. 更新 HTML 以将 Angular 的 ViewChild 用于数据表

import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Subject } from 'rxjs';
import { DataTableDirective } from 'angular-datatables';

@Component({
  selector: 'app-data-table',
  templateUrl: './data-table.component.html',
  styleUrls: ['./data-table.component.css']
})
export class DataTableComponent implements OnInit, OnDestroy {
  @ViewChild(DataTableDirective, { static: false }) dtElement: DataTableDirective;
  dtOptions: DataTables.Settings = {};
  dtTrigger: Subject<any> = new Subject<any>();
  posts: any[] = [];
  searchTerm: string = '';

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.dtOptions = {
      pagingType: 'full_numbers',
      pageLength: 10,
      destroy: true
    };

    // Fetch initial data
    this.fetchData();
  }

  fetchData(): void {
    this.http.get('https://jsonplaceholder.typicode.com/posts')
      .subscribe((posts: any[]) => {
        this.posts = posts;
        this.dtTrigger.next(null);
      });
  }

  searchPosts(): void {
    if (this.searchTerm.trim() === '') {
      this.fetchData(); // If search term is empty, fetch all data
    } else {
      this.http.get(`https://jsonplaceholder.typicode.com/posts?title_like=${this.searchTerm}`)
        .subscribe((posts: any[]) => {
          this.posts = posts;
          this.rerender();
        });
    }
  }

  rerender(): void {
    this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
      dtInstance.destroy();
      this.dtTrigger.next(null);
    });
  }

  ngOnDestroy(): void {
    this.dtTrigger.unsubscribe();
  }
}
<div class="search-container">
  <input type="text" [(ngModel)]="searchTerm" placeholder="Search by title" />
  <button (click)="searchPosts()">Search</button>
</div>

<table #dataTable datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger" class="row-border hover">
  <thead>
    <tr>
      <th>ID</th>
      <th>Title</th>
      <th>Body</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let post of posts">
      <td>{{ post.id }}</td>
      <td>{{ post.title }}</td>
      <td>{{ post.body }}</td>
    </tr>
  </tbody>
</table>

希望这对你有用:)

© www.soinside.com 2019 - 2024. All rights reserved.