我正在使用 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-Datatables 中的数据后正确重新渲染 DataTable,您需要确保正确处理 DataTable 实例的生命周期。以下是解决该问题的详细方法:
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>
希望这对你有用:)