2017-05-05 4 views
4

Ich bekomme eine Observable zurück von einem Datendienst zu Web-API, die ein Array zurückgibt und eine Datentabelle in einer übergeordneten Komponente richtig auffüllt. Ich gebe das Array, das zum Füllen der Datentabelle mit einer untergeordneten Komponente verwendet wird, über @Input weiter. Wenn auf eine Zeile in der übergeordneten Komponente geklickt wird, zeige ich ein Modal zum Bearbeiten einer einzelnen Zeile mit einem Formular an. Wenn die Schaltfläche zum Speichern auf das Modal geklickt wird, werden die Zeileninformationen an die untergeordnete Komponente gesendet, die den Server aufruft und die Informationen korrekt aktualisiert. Der Server gibt das aktualisierte Objekt zurück, das dann in das @ Input-Array gespleißt wird. Die Datentabelle wird nie aktualisiert, obwohl ich sehen kann, dass die Änderungen am Modellarray auftreten und von Angular mithilfe von Augury erkannt werden. Ich habe versucht, mit NgZone, NgOnChanges und Setter/Getter das Array gezwungen, zu aktualisieren, ohne Erfolg. Ich habe genau denselben Code in einem anderen Projekt und es funktioniert wie erwartet. Ich bin mir nicht sicher, was ich hier vermisse.Angular4 PrimeNG DataTable wird trotz Modelländerungen nicht aktualisiert

Eltern Vorlage

<h2>Website Aliases</h2> 

<p-dataTable #dt [value]="websiteAliases" selectionMode="single" [(selection)]="selectedWebsiteAlias" 
      (onRowSelect)="onRowSelect($event);wad.setEditValue(selectedWebsiteAlias)" 
      [paginator]="true" [rows]="100" 
      [sortMode]="multiple"> 
    <p-header> 
     Website Aliases 
     <div style="float:right;"> 
      <button pButton type="button" (click)="wad.setCreateValue();" icon="fa-plus"></button> 
      <button pButton type="button" (click)="reloadDataTable();" icon="fa-refresh"></button> 
     </div> 
    </p-header> 
    <p-column field="aliasID" header="Alias ID" sortable="true"></p-column> 
    <p-column field="webID" header="Web ID" [filter]="true" filterMatchMode="contains"></p-column> 
    <p-column field="csHost" header="CsHost" [filter]="true" filterMatchMode="contains"></p-column> 
</p-dataTable> 

    <website-alias-detail #wad [websiteAlias]="selectedWebsiteAlias" [websiteAliases]="websiteAliases"></website-alias-detail> 

geordnete Komponente

import { Observable } from 'rxjs/Rx'; 
import { DataTableModule, DialogModule } from 'primeng/primeng'; 
import { WebsiteAliasDetailComponent } from './websitealiasdetails.component'; 

@Component({ 
    selector: 'website-alias', 
    templateUrl: 'websitealias.component.html' 
}) 

export class WebsiteAliasComponent { 
    constructor(private dataService: DataService) { } 
    private websiteAliases: WebsiteAlias[]; 
    private selectedWebsiteAlias: WebsiteAlias; 


    ngOnInit(): void { 
     this.dataService.get('websitealias').subscribe(apiObjects => this.websiteAliases = apiObjects); 
    } 

    onRowSelect(row): void { 
     this.selectedWebsiteAlias = this.websiteAliases.find(websiteAlias => websiteAlias.aliasID === row.data.aliasID); 
    } 

    createWebsiteAlias(): void { 
     this.selectedWebsiteAlias = null; 
    } 

    reloadDataTable(): void { 
     this.dataService.get('websitealias').subscribe(apiObjects => this.websiteAliases = apiObjects); 
    } 
} 

Kinder Vorlage

<p-dialog #dialog modal="true" header="Website Alias Details" [(visible)]="display"> 
    <form #form [formGroup]="alias"> 
     <div class="alert alert-danger" [hidden]="alias.controls.webID.valid || (alias.controls.webID.pristine && !submitted)"> 
      Web ID is required and only accepts numbers 
     </div> 
     <div class="alert alert-danger" [hidden]="alias.controls.csHost.valid || (alias.controls.csHost.pristine && !submitted)"> 
      CS Host is required 
     </div> 
     <div class="divTable"> 
      <div class="divTableBody"> 
       <div class="divTableRow" *ngIf="alias"> 
        <div class="divTableCell"><label>Alias ID: </label></div> 
        <div class="divTableCell"><label><input placeholder="Alias ID" formControlName="aliasID" readonly="readonly" /></label></div> 
       </div> 
       <div class="divTableRow"> 
        <div class="divTableCell"><label>Web ID: </label></div> 
        <div class="divTableCell"><input placeholder="Web ID" formControlName="webID" /></div> 
       </div> 
       <div class="divTableRow"> 
        <div class="divTableCell"><label>CS Host: </label></div> 
        <div class="divTableCell"><input placeholder="CS Host" formControlName="csHost" /></div> 
       </div> 
       <div class="divTableRow"> 
        <div class="divTableCell"> 
         <button pButton type="submit" label="Save" (click)="saveWebsiteAlias(alias.value)" [disabled]="alias.invalid" class="ui-button ui-button-primary"></button> 
         <button pButton type="button" label="Close" (click)="hideDialog();" class="ui-button ui-button-secondary"></button> 
         <button *ngIf="websiteAlias" pButton type="submit" label="Delete" (click)="deleteWebsiteAlias(alias.value)" class="ui-button ui-button-danger"></button> 
        </div> 
       </div> 
      </div> 
     </div> 
    </form> 
</p-dialog> 

Child Component

import { Component, Input, Output, OnInit, ViewEncapsulation } from '@angular/core'; 
import { DataService } from '../../services/data.service'; 
import { WebsiteAlias } from './WebsiteAlias'; 
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms'; 

@Component({ 
    selector: 'website-alias-detail', 
    templateUrl: 'websitealiasdetails.component.html', 
    encapsulation: ViewEncapsulation.None, 

}) 

export class WebsiteAliasDetailComponent implements OnInit { 
    @Input() websiteAliases: WebsiteAlias[]; 
    @Input() websiteAlias: WebsiteAlias; 

    public alias: FormGroup; 
    private api = 'websitealias'; 
    private display: boolean = false; 
    private isEdited: boolean = false; 

    constructor(private dataService: DataService, private formBuilder: FormBuilder) { } 

    ngOnInit(): void { 
     this.alias = this.formBuilder.group({ 
      aliasID: [''], 
      webID: ['', [Validators.required, Validators.pattern('[0-9]*')]], 
      csHost: ['',Validators.required] 
     }); 

    } 


    setEditValue(websiteAlias: WebsiteAlias) 
    { 
     this.alias.patchValue({ aliasID: websiteAlias.aliasID, webID: websiteAlias.webID, csHost: websiteAlias.csHost}); 
     this.isEdited = true; 
     this.showDialog(); 
    } 

    setCreateValue() 
    { 
     this.alias.patchValue({ aliasID: '', webID: '', csHost: '' }); 
     this.isEdited = false; 
     this.websiteAlias = null; 
     this.showDialog(); 
    } 


    showDialog(): void { 

     this.display = true; 
    } 

    hideDialog(): void { 
     this.display = false; 
    } 

    saveWebsiteAlias(savedAlias: WebsiteAlias): void { 

     if (!this.isEdited) 
      this.createWebsiteAlias(savedAlias);    
     else { 
      this.editWebsiteAlias(savedAlias); 
     } 

     this.hideDialog(); 
    } 

    deleteWebsiteAlias(deletedAlias: WebsiteAlias): void { 

     var idToDelete = 0; 
     this.dataService.delete(this.api, deletedAlias.aliasID).subscribe(deletedId => idToDelete = deletedId); 

     let websiteAliasToRemove = this.websiteAliases.find(web => web.aliasID === idToDelete); 
     let index: number = this.websiteAliases.indexOf(websiteAliasToRemove); 
     this.websiteAliases.splice(index, 1); 

     this.hideDialog(); 

    } 

    createWebsiteAlias(createdAlias: WebsiteAlias): void { 

     var newAlias = new WebsiteAlias(0, createdAlias.webID, createdAlias.csHost); 

     this.dataService.post(this.api, newAlias).subscribe(apiObject => newAlias.aliasID = apiObject.aliasID); 

     this.websiteAliases.push(newAlias); 
     this.websiteAlias = newAlias; 

    } 

    editWebsiteAlias(updatedAlias: WebsiteAlias): void { 
     var idToUpdate = 0; 
     var aliases = this.websiteAliases; 
     this.dataService.put(this.api, updatedAlias).subscribe(apiObject => this.websiteAlias = apiObject); 
     let websiteAliasToEdit = aliases.find(web => web.aliasID === updatedAlias.aliasID); 
     let index: number = aliases.indexOf(websiteAliasToEdit); 
     this.websiteAliases.splice(index, 1, updatedAlias); 
    } 

} 
+0

Können Sie einen funktionierenden Plünderer erstellen? – Aravind

Antwort

2

Schauen Sie sich die Antwort in [How to programmaticaly trigger refresh primeNG datatable when a button is clicked Frage: 1

Ich habe nicht genug rep dies als Kommentar zu schreiben, aber die Antwort beinhaltet eine „sichtbare“ Variable Schaffung mit * ngIf, um das Wiederherstellen der DOm auszulösen.

+0

yeah Ich habe mich gerade für eine Aktualisierung der Daten entschieden, ohne das dom neu zu erstellen - der Anwendungsfall war, dass wir möglicherweise zusätzliche Benutzer Änderungen vornehmen ließen. Daher wollten wir sicherstellen, dass alle Änderungen erfasst werden und nicht nur die im Browser des Benutzers. – xyntiacat

Verwandte Themen