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);
}
}
Können Sie einen funktionierenden Plünderer erstellen? – Aravind