【发布时间】:2020-09-02 09:23:15
【问题描述】:
我使用 mat-dialog 来编辑我的个人资料页面的详细信息。当我单击“编辑年龄”按钮并弹出对话框窗口时,我收到 ExpressionChangedAfterItHasBeenCheckedError。
我决定将所有编辑对话框的样式提取到单个 edit.component 中:
edit.component.html
<div class="navigation-control">
<mat-icon (click)="onCancelButtonClicked()"
class="close-button">close</mat-icon>
</div>
<div class="content-main">
<ng-content select=".content-main"></ng-content>
</div>
<div class="content-bot">
<button mat-raised-button
(click)="onCancelButtonClicked()">Cancel</button>
<button mat-raised-button
(click)="onActionButtonClicked()"
[lnDisableButton]="actionButtonDisabled">{{actionButtonValue}}</button>
</div>
edit.component.ts
@Component({ selector: 'ln-edit', ... })
export class EditComponent {
@Input() actionButtonValue: string;
@Input() actionButtonDisabled: boolean;
@Output() cancelButtonClicked = new EventEmitter<void>();
@Output() actionButtonClicked = new EventEmitter<void>();
onCancelButtonClicked() {
this.cancelButtonClicked.emit();
}
onActionButtonClicked() {
this.actionButtonClicked.emit();
}
}
为了避免在尝试禁用按钮和控件时出现 ExpressionChangedAfterItHasBeenCheckedError,我使用了这个 sn-p。但这并没有解决这个问题。
disable-button.directive.ts
@Directive({ selector: '[lnDisableButton]' })
export class DisableButtonDirective {
@Input('lnDisableButton') isDisabled = false;
@HostBinding('attr.disabled')
get disabled() { return this.isDisabled; }
}
以下是mat-dialog 窗口的内容。当我单击“编辑年龄”按钮时,它会被实例化。当我删除 [actionButtonDisabled]="actionButtonDisabled" 时,错误消失了,但显然我需要该行来使功能禁用按钮。
age-edit.component.html
<ln-edit [actionButtonValue]="actionButtonValue"
[actionButtonDisabled]="actionButtonDisabled"
(cancelButtonClicked)="onCancelButtonClicked()"
(actionButtonClicked)="onActionButtonClicked()">
<form [formGroup]="ageForm"
class="content-main">
<ln-datepicker formControlName="birthday"
[appearance]="'standard'"
[label]="'Birthday'"
class="form-field">
</ln-datepicker>
</form>
</ln-edit>
我在 mat-dialog 弹出窗口的“ts”部分处理禁用/启用按钮。
age-edit.component.ts
@Component({ selector: 'ln-age-edit', ... })
export class AgeEditComponent implements OnInit, OnDestroy {
ageForm: FormGroup;
private initialFormValue: any;
actionButtonDisabled = true;
private unsubscribe = new Subject<void>();
constructor(
private editPhotoDialogRef: MatDialogRef<AgeEditComponent>,
private fb: FormBuilder,
@Inject(MAT_DIALOG_DATA) public dialogData: Date) { }
ngOnInit() {
this.initializeAgeForm();
this.loadDataToAgeForm(this.dialogData);
this.trackFormDistinct();
}
private initializeAgeForm(): void {
this.ageForm = this.fb.group({
birthday: null,
});
}
loadDataToAgeForm(birthday: Date | null): void {
if (!birthday) { return; }
this.ageForm.setValue({ birthday });
this.initialFormValue = this.ageForm.value;
}
get birthdayAC() { return this.ageForm.get('birthday') as AbstractControl; }
get actionButtonValue(): string {
return this.birthdayAC.value ? 'Update age' : 'Add age';
}
onCancelButtonClicked(): void {
this.editPhotoDialogRef.close();
}
onActionButtonClicked(): void {
this.editPhotoDialogRef.close({ ... });
}
trackFormDistinct(): void {
this.ageForm.valueChanges.pipe(
distinctUntilChanged(), // TODO: needed?
takeUntil(this.unsubscribe)
).subscribe(val => {
(this.formValueNotDistinct(this.ageForm.value, this.initialFormValue)
|| this.birthdayAC.value === null)
? this.actionButtonDisabled = true
: this.actionButtonDisabled = false;
});
}
ngOnDestroy() { ... }
}
我怀疑这与内容投影有关,但我不确定。
(......或者也许我的自定义'ln-datepicker'?)
有任何想法吗?
谢谢。
【问题讨论】:
-
能否也添加积分错误信息?
-
@AndreiGătej - 你的意思是整个错误信息吗?还是别的什么?
-
对不起,我只想说相关部分:从
X更改为Y -
你是这个意思吗? ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:“真”。当前值:“假”。在 throwErrorIfNoChangesMode (core.js:8092) at bindingUpdated (core.js:19773) at ɵɵproperty (core.js:20921) at AgeEditComponent_Template (age-edit.component.html:2) at executeTemplate (core.js:11949) at refreshView (core.js:11796) 在 refreshComponent (core.js:13229) 在 refreshChildComponents (core.js:11527) 在 refreshView (core.js:11848) 在 refreshDynamicEmbeddedViews (core.js:13154)
标签: html angular typescript