1
votes

L'actualisation des données de la table datatables.net dans Angular 7 conserve une copie des anciennes données du premier chargement de la table

J'essaie de créer un rapport en direct à partir d'une demande d'API REST en utilisant la bibliothèque datatables.net dans Angular 7. Si j'effectue une mise à jour des données dans la base de données, les données du tableau sont mises à jour. Cependant, si je touche le tableau (c'est-à-dire réorganiser, rechercher quelque chose, changer la page, etc.), lors du rechargement des données (qui se produit toutes les 5 secondes), dans le tableau sont ajoutées les données du premier chargement de la table. Si je touche à nouveau le tableau, les données mises à jour disparaissent, et seules les anciennes données restent, jusqu'à la prochaine mise à jour des données, lorsque les nouvelles données sont à nouveau ajoutées dans le tableau.

C'est l'état du tableau lorsque la page se charge État de la table lors du chargement de la page

C'est l'état de la table lorsque les données de la base de données sont mises à jour

 état de la table lorsque les données de la base de données sont mises à jour

Il s'agit du comportement de la table lorsque des modifications sont apportées à la table (par exemple, trier, rechercher, changer de page, etc.) comportement de la table lorsqu'une modification est apportée à la table

Voici le code du composant:

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

et voici le fichier html

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


2 commentaires

pouvez-vous publier votre fichier html


bien sûr, je l'ai ajouté maintenant


4 Réponses :


0
votes

Je l'ai essayé et ce comportement est très étrange, il revient par défaut aux valeurs d'origine. Ce n'est pas un problème avec votre code mais plutôt avec une bibliothèque angulaire datable.

Pour l'instant rétrogradez vers angular-datatables@6.0.0 en utilisant

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

Je l'ai essayé et cela fonctionne très bien.


3 commentaires

Bonjour, j'ai essayé votre solution, mais elle n'a pas résolu le problème.


hmm si cela ne fonctionne pas, pouvez-vous essayer de détruire l'instance datable et de la relancer à nouveau? l-lin.github.io/angular-datatables/#/advanced/ rendre


J'ai également essayé la solution d'ici: github.com/l-lin/ angular-datatables / issues / 1146 . Malheureusement, rien ne semble fonctionner.



2
votes

Vous devez d'abord détruire la table et effectuer un nouveau rendu. Vous pouvez consulter l'article ici . Un extrait de code si le lien est désactivé à l'avenir.

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

Une autre solution est comme indiqué ici

Faites-moi savoir si cette solution fonctionne ou si vous avez des questions.


0 commentaires

0
votes

J'ai eu le même problème. L'appel du dtTrigger après un rappel de ma méthode de mise à jour des données l'a résolu:

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

    })
  });
 }


0 commentaires

0
votes

J'ai fait un exemple de comment cela peut bien fonctionner lorsque vous essayez de faire un rendu sur angular-datatables . Cela fonctionne sur Angular 9. Vous devez utiliser ChangeDetectorRef car classe de base qui fournit la fonctionnalité de détection des modifications. Une arborescence de détection des modifications rassemble toutes les vues dont les modifications doivent être vérifiées. Utilisez les méthodes pour ajouter et supprimer des vues de l'arborescence, lancer la détection des modifications et marquer explicitement les vues comme sales, ce qui signifie qu'elles ont été modifiées et doivent être rendues à nouveau. Découvrez-le: https://angular.io/api/core/ChangeDetectorRef

stuff.html

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

stuff.ts^

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

p >


0 commentaires