Refreshing datatables.net table data in Angular 7

2019-08-01 03:52发布

问题:

I'm trying to make a live reporting from a REST API request using the datatables.net library in Angular 7. If I make a data update into the database, the data in the table is updated. However, If I touch the table (i.e. reorder, search for something, change the page, etc), on data reloading (which occurs every 5 seconds), in the table is added the data from the first load of the table. If I touch the table again, the updated data disappears, and only the old data remains, until the next data update, when the new data is added again in the table.

This is the state of the table when the page loads

This is the state of the table when the data in the database is updated

This is the behavior of the table when any change is made on the table (i.e. sort, search, switch page, etc)

This is the code for the component:

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();
  }
}

and this is the html file

<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>

回答1:

You have to destroy the table first and re render. You can refer the article here. A code snippet if link gets disabled in future.

rerender(): void {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
  // Destroy the table first
  dtInstance.destroy();
  // Call the dtTrigger to rerender again
  this.dtTrigger.next();
});
}

Another solution is as discussed here

Let me know if this solution works or if you have any query.



回答2:

I tried it out and this behavior is very weird, it defaults back to the original values. This is not a problem with your code but instead with angular-datatable library.

For the meantime downgrade to angular-datatables@6.0.0 using

npm install --save angular-datatables@6.0.0 or yarn add angular-datatables@6.0.0

I tried it out and it works fine.