【问题标题】:Refreshing datatables.net table data in Angular 7 keeps a copy of the old data from table's first loading在 Angular 7 中刷新 datatables.net 表数据会保留表第一次加载时的旧数据副本
【发布时间】:2019-02-24 00:35:11
【问题描述】:

我正在尝试使用 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>

【问题讨论】:

  • 你能发布你的html文件吗
  • 当然,我现在添加了它

标签: angular datatables angular7 angular-datatables


【解决方案1】:

你必须先销毁表并重新渲染。可以参考文章here。 如果链接将来被禁用,则代码 sn-p。

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所讨论的那样

如果此解决方案有效或您有任何疑问,请告诉我。

【讨论】:

    【解决方案2】:

    我试过了,这种行为很奇怪,它默认恢复为原始值。这不是您的代码的问题,而是 angular-datatable 库的问题。

    同时降级到 angular-datatables@6.0.0 使用

    npm install --save angular-datatables@6.0.0 要么 yarn add angular-datatables@6.0.0

    我试过了,效果很好。

    【讨论】:

    【解决方案3】:

    我遇到了同样的问题。在我的数据更新方法回调后调用 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();
    
        })
      });
     }
    

    【讨论】:

      【解决方案4】:

      我做了一个示例,当您尝试在 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();
                  });
              });
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-07-06
        • 2018-11-14
        • 2021-09-08
        • 1970-01-01
        • 1970-01-01
        • 2019-09-14
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        相关资源
        最近更新 更多