web-dev-qa-db-fra.com

PrimeNg datatable n'actualise pas

Utiliser Angular v2.4.8 et PrimeNg v1.1.4

J'ai une page avec deux composants:

  1. Dropzone, pour le téléchargement de fichiers
  2. p-datatable pour montrer les fichiers téléchargés

J'ai configuré Dropzone pour envoyer 5 fichiers à la fois et quand il en a fini avec 5 fichiers l'événement onDropZoneSendingMultiple est déclenché. Lorsque tous les fichiers sont téléchargés, la variable onDropZoneQueueComplete est générée.

Dans les deux auditeurs, je veux actualiser le datatable qui est dans le deuxième composant. Ceci ne fonctionne pas. J'ai besoin d'actualiser la page pour voir les nouveaux fichiers.

Mon HTML de la page principale:

<div class="row" id="dropzoneContainer">
    <dropzone class="dropzone" #dz [config]="dropZoneConfig" 
              (error)="onDropZoneUploadError($event)"
              (sendingmultiple)="onDropZoneSendingMultiple($event)"
              (queuecomplete)="onDropZoneQueueComplete($event, dz);"
              (maxfilesreached)="onDropZoneMaxfilesReached($event)"
              (maxfilesexceeded)="onDropZoneMaxfilesExceeded"></dropzone>
</div>

<div class="row">
    <div class="col-md-12">
        <FilesList></FilesList>
    </div>
</div>

Le composant Dropzone- affiche la zone de dépôt. La FilesList montre le datatable . Une partie du HTML:

<p-dataTable [hidden]="loading" [value]="files" selectionMode="single" (onRowSelect)="details($event)">

Dans mon fichier principal, j'ai:

@ViewChild(FilesListComponent)
public filesListComponent: FilesListComponent;

private reloadFileList() {
  this.filesListComponent.reload();
}

Dans ma liste de dossiers, j'ai

public files: File[];
public reload() {
    this.getFiles();
}
public getFiles() {
    this.fileService.getAll()
        .then(
        data => {
            this.files = data;
        });
}

getFiles est également appelé au chargement de la page . Lorsque j'ajoute des instructions console.log(), je peux voir que getFiles() est appelé et que this.files est mis à jour, mais la table n'est pas actualisée.

11
Paul Meems

Pour ceux qui recherchent encore la nouvelle syntaxe consistant à ajouter des enregistrements à un tableau lié à une table primeng

this.arrayRecords= [...this.arrayRecords, newObject];

14
karthiks3000

Update: PrimeNG a récemment supprimé l'interface DoCheck qui détectait automatiquement les modifications. Voir: https://www.primefaces.org/primeng-4-0-0-rc4-released/

La solution consiste à utiliser l'opérateur de propagation ([... arr] - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator ) pour ajouter des éléments à votre tableau au lieu de .Push ().


Réponse originale: J'ai eu un problème similaire que j'ai résolu en utilisant une approche légèrement différente. Si vous utilisez le même service pour télécharger et récupérer vos fichiers, vous pouvez utiliser RxJS au lieu d'écouter les événements de tous les composants.

Sur mes services, je souhaite recharger l'application lorsque je crée un POST ou que je l'utilise:

  private _shouldUpdateSource = new BehaviorSubject<boolean>(false);
  shouldUpdateObservable = this._shouldUpdateSource.asObservable();

Dans vos méthodes POST et/ou PUT 

this.http.post(..).map( res => {this._shouldUpdateSource.next(true);});

Ce qui vous permet de vous abonner à fileService.shouldUpdateObservable dans vos composants:

 this.shouldUpdateSub = this.fileService.shouldUpdateObservable
  .subscribe((shouldUpdate: boolean) => {
    if (shouldUpdate) {
      this.updateFiles();
    }
  });

Cela semble être le meilleur moyen de gérer la communication d’un service entre les composants que j’ai vus/utilisés.

-Edit-Voici le même concept dans la documentation officielle:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

-Edit 2 - J'ai rencontré à nouveau ce problème après la mise à jour vers la version 4.0.0. FWIW, j'ai fini par retirer le PrimeNG Datatable, en utilisant plutôt un manuel * ngFor et cela a bien fonctionné. Il semble que la documentation PrimeNg ( https://www.primefaces.org/primeng/#/datatable ) vous indique de:

"Par exemple, utilisez slice au lieu de splice lors de la suppression d'un élément ou utilisez l'opérateur spread au lieu de la méthode Push pour l'ajout d'un élément."

Je ne sais pas trop pourquoi ils vous demandent de le faire car cela est contraire à la documentation officielle d'Angular, mais je pense que cela a quelque chose à voir avec pourquoi la liaison de [value] ne fonctionne pas comme prévu.

Personnellement, je m'éloigne de PrimeNg au profit de la table de données Covalent qui a une fonction explicite de rafraîchissement (): https://teradata.github.io/covalent/#/components/data-table

9
rbj325

Je soupçonne que cela a à voir avec la façon dont votre composant enfant gère les changements. Vous devez implémenter l'événement onChange et définir les fichiers de cette manière. Voici un exemple:

`` `

export class FilesListComponent implements OnChanges {
    @Input() files: File[];

    ngOnInit() {
    }

    // Subscribe to the change event and update the model
    ngOnChanges(changes: {[propName: string]: SimpleChange}) {
        let key = 'files';
        this.files = changes[key].currentValue;
    }
}

`` `

1
Ben Richards

Nous pouvons marquer la vue pour vérification et appeler detechchange.

@ViewChild('searchDt') searchTable: DataTable;


self.dealService.getAccounts(self.searchParams).subscribe((response) => {       
   Deal.setAvailableAccount(response.map((current) => {
     return {
        "cifNumber": current['cif'],
        "ucic": current['ucic'],
        "accountNomenclature": current['customerName'],
     }
   }));

   **self.searchTable.changeDetector.markForCheck();
   self.searchTable.changeDetector.detectChanges();**
});
0
blazehub