此处提供了Plunker:http://plnkr.co/edit/vczMKlnY5yxXtzrh955m?p=preview
用例看起来很简单:
在弹出窗口中保存单击,我想更新实体。 在弹出窗口关闭时,我想取消选择该行。
通过在updateSuccess事件中将选择设置为null,保存时的错误消失(在plunker中TRICK 1)。
我设法找到完全防止错误的唯一解决方案是禁用通过交叉使用# Sample list of data.frame's
lst <- list(
data.frame(one = letters[1:10], two = 1:10),
data.frame(one = letters[11:20], two = 11:20))
# Concatenate row number with entries in second column
lapply(lst, function(x) { x$three <- paste(1:nrow(x), x$two, sep = "_"); x })
#[1]]
# one two three
#1 a 1 1_1
#2 b 2 2_2
#3 c 3 3_3
#4 d 4 4_4
#5 e 5 5_5
#6 f 6 6_6
#7 g 7 7_7
#8 h 8 8_8
#9 i 9 9_9
#10 j 10 10_10
#
#[[2]]
# one two three
#1 k 11 1_11
#2 l 12 2_12
#3 m 13 3_13
#4 n 14 4_14
#5 o 15 5_15
#6 p 16 6_16
#7 q 17 7_17
#8 r 18 8_18
#9 s 19 9_19
#10 t 20 10_20
关闭弹出窗口的可能性,并且永远不会处理弹出窗口中的显示布尔值,而是将此责任委托给父组件(使用父级中的close事件将显示设置为false)(在plunker中TRICK 1 + TRICK 2)。
如果没有添加一些技巧来强制绑定手动刷新,我无法找到一个好的解决方案。
这里最好的解决方案是什么?
app / app.component.ts:
[closable]="false"
app / app.template.html:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: 'app/app.template.html'
})
export class AppComponent {
public display = false;
public selectedEntity = null;
public cols = [
{field: 'id', header: 'ID'},
{field: 'prop', header: 'Property'}
];
public someEntities = [
{ id: 1, prop: 'foo' },
{ id: 2, prop: 'bar' }
];
public onClick() {
this.display = true;
}
public onRowSelect(event) {
this.display = true;
}
public onClose() {
this.selectedEntity = null;
// XXX TRICK 2 : Uncomment to delegate the closing responsibility to this component
//this.display = false;
}
public onUpdateSuccess() {
// XXX TRICK 1 : Uncomment to prevent the error on save
//this.selectedEntity = null;
// XXX TRICK 2 : Uncomment to delegate the closing responsibility to this component
//this.display = false;
}
}
应用程序/ popup.component.ts
<h2>PrimeNG Issue Template</h2>
<p>Please create a test case and attach the link of the plunkr to your github issue report.</p>
<p-table [columns]="cols" [value]="someEntities" (onRowSelect)="onRowSelect($event)" selectionMode="single" [(selection)]="selectedEntity">
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr [pSelectableRow]="rowData">
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
<my-popup [(display)]="display" [myEntity]="selectedEntity" (close)="onClose()" (updateSuccess)="onUpdateSuccess($event)"></my-popup>
应用程序/ popup.component.html
import { Component, Input, Output, OnChanges, EventEmitter } from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'my-popup',
templateUrl: 'app/popup.component.html'
})
export class MyPopupComponent implements OnChanges {
private _display = false;
@Input()
get display() {
return this._display;
}
set display(_display: boolean) {
this._display = _display;
this.displayChange.emit(_display);
}
@Input()
public myEntity: any;
@Output()
private displayChange = new EventEmitter<boolean>();
@Output()
public close = new EventEmitter<void>();
@Output()
public updateSuccess = new EventEmitter<any>();
public myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
myProp: ['', []]
});
}
ngOnChanges() {
if (this.display === true && this.myEntity) {
this.myForm.reset({myProp: this.myEntity.prop});
}
}
public onHide() {
this.close.emit();
}
public onSubmit() {
this.myEntity.prop = this.myForm.value.myProp;
// Call to REST API to update the entity then emit the success
this.updateSuccess.emit();
// XXX TRICK 2 : Comment to delegate the closing responsibility to the parent component
this.display = false;
}
}
答案 0 :(得分:0)
要摆脱ExpressionChangedAfterItHasBeenCheckedError
,您必须在app.component中手动触发更改检测(请参阅Expression ___ has changed after it was checked)
因此,您的onClose
方法变为:
public onClose() {
this.selectedEntity = {};
this.cdr.detectChanges();
}
请参阅Plunker