Utiliser Angular v2.4.8 et PrimeNg v1.1.4
J'ai une page avec deux composants:
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.
Pour ceux qui recherchent encore la nouvelle syntaxe consistant à ajouter des enregistrements à un tableau lié à une table primeng
this.arrayRecords= [...this.arrayRecords, newObject];
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
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;
}
}
`` `
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();**
});