我正在尝试使用Angular 7中的datatables.net库根据REST API请求进行实时报告。如果我对数据库进行数据更新,则表中的数据将更新。但是,如果我触摸表(即重新排序,搜索内容,更改页面等),则在数据重新加载时(每5秒发生一次),表中的数据会从表的第一次加载中添加。如果我再次触摸该表,则更新的数据将消失,仅保留旧数据,直到下一次数据更新时,才将新数据再次添加到表中。
这是更新数据库中数据时表的状态
这是在表格上进行任何更改(即排序,搜索,切换页面等)时表格的行为
这是组件的代码:
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Subject } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { DownloadService } from '../services/download/download.service';
import { stringify } from 'querystring';
import { Router } from '@angular/router';
@Component({
selector: 'app-downloads',
templateUrl: './downloads.component.html',
styleUrls: ['./downloads.component.css']
})
export class DownloadsComponent implements OnInit {
downloadData$: any[] = [];
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
interval: any;
constructor(private http: HttpClient, private data: DownloadService, private router: Router) { }
ngOnInit() {
this.dtOptions = {
responsive: true
};
this.data.GetDownloads().subscribe(data => {
this.downloadData$ = data;
this.dtTrigger.next();
});
this.interval = setInterval(() => {
this.refreshData();
}, 5000);
}
refreshData() {
this.data.GetDownloads().subscribe(data => {
this.downloadData$ = data;
});
}
ngOnDestroy(): void {
this.dtTrigger.unsubscribe();
}
}
这是html文件
<div>
<table style="text-align: center;" class="table table-striped table-bordered table-hover" cellspacing="0" width="100%"
datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger">
<thead>
<tr>
<th>Logger Name</th>
<th>Progress</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let download of downloadData$">
<td>{{ download.logger.name }}</td>
<td [attr.data-order]="download.progress"><progress [attr.value]="download.progress" max="100"></progress>
{{ download.progress }}%</td>
</tr>
</tbody>
</table>
</div>
答案 0 :(得分:1)
您必须先销毁表格并重新渲染。您可以参阅文章here。 如果将来会禁用链接,则为代码段。
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
// Destroy the table first
dtInstance.destroy();
// Call the dtTrigger to rerender again
this.dtTrigger.next();
});
}
另一种解决方案如所讨论的here
让我知道此解决方案是否有效,或者您有任何疑问。
答案 1 :(得分:0)
我尝试了一下,这种行为非常奇怪,它默认恢复为原始值。这不是代码的问题,而是angular-datatable库的问题。
同时使用
降级到angular-datatables@6.0.0 npm install --save angular-datatables@6.0.0
要么
yarn add angular-datatables@6.0.0
我尝试了一下,效果很好。
答案 2 :(得分:0)
我有同样的问题。从我的数据更新方法回调后调用dtTrigger解决了该问题:
rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
// Destroy the table first
dtInstance.destroy();
//reload your data
this.reloadDataMethod(()=>{
// Call the dtTrigger to rerender **after callback**
this.dtTrigger.next();
})
});
}
答案 3 :(得分:0)
当您尝试对 angular-datatables 进行渲染时,我做了一个示例,说明它如何正常工作。它适用于Angular 9。 您必须使用ChangeDetectorRef,因为提供更改检测功能的基类。更改检测树收集所有要检查更改的视图。使用这些方法可以在树中添加和删除视图,启动更改检测以及将视图明确标记为脏视图,这意味着它们已经更改并且需要重新呈现。 签出:https://angular.io/api/core/ChangeDetectorRef
stuff.html
<table
datatable
*ngIf="myData.length"
[dtOptions]="dtOptions"
[dtTrigger]="dtTrigger"
class="table table-bordered table-striped"
>
<thead>
<tr>
<th> Stuff1 </th>
<th> Stuff2 </th>
<th> Stuff3 </th>
<th> Stuff4 </th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of myData">
<td> {{ data.stuff1 }} </td>
<td> {{ data.stuff2 }} </td>
<td> {{ data.stuff3 }} </td>
<td> {{ data.stuff4 }} °C </td>
</tr>
</tbody>
</table>
stuff.ts
@Component({
selector: 'app-stuff',
templateUrl: './stuff.component.html'
})
export class DetailComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild(DataTableDirective) datatableElement: DataTableDirective;
public dtOptions: DataTables.Settings = {};
public dtTrigger: Subject<any> = new Subject();
constructor(
private readonly chRef: ChangeDetectorRef,
private readonly stuffService: StuffService
) { }
ngOnInit() {
this.stuffService.list().subscribe(response => {
this.myData = response;
//put this line before call dtTrigger
this.chRef.detectChanges();
this.dtTrigger.next();
});
}
ngOnDestroy() {
this.dtTrigger.unsubscribe();
}
ngAfterViewInit() {
this.dtTrigger.next();
}
public rerender() {
this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.destroy();
this.stuffService.list().subscribe(response => {
this.myData = response;
this.dtTrigger.next();
});
});
}
}