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
C'est l'é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.)
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(); } }
4 Réponses :
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.
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.
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.
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(); }) }); }
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 >
pouvez-vous publier votre fichier html
bien sûr, je l'ai ajouté maintenant