Hey Stackoverflow社区,
我发现了一个奇怪的问题,发现了一个肮脏的解决方法。 这里的问题,我有一个选择框有一些选项。如果用户选择一个特定的选项,我会显示一个模态框,但这里有问题,当我打开模式时,用户点击该选项时出现错误。控制器在这里是ReactiveForms的FormControl
controle.valueChanges.subscribe(value => {
if (value === 'SOME_EQUALS') {
this.modalService.open<SomeModalComponent>(SomeModalComponent);
}
});
确切错误:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ng-untouched: true'. Current value: 'ng-untouched: false'.
肮脏的解决方法是,在那个值是quals的那一刻我期望我分离ChangeDetectionRef然后打开模态,当我关闭模态我重新连接cdr ...
controle.valueChanges.subscribe(value => {
if (value === 'SOME_EQUALS') {
// ChangeDetectionRef
this.cdr.detach();
const modal = this.modalService.open<SomeModalComponent>(SomeModalComponent);
modal.onClose().subscribe(() => this.cdr.reattach());
modal.onDismiss().subscribe(() => this.cdr.reattach());
}
});
你知道一种更美丽的方式吗?
答案 0 :(得分:1)
我假设您使用材质库?
如果是这样,您必须绑定到复选框的更改事件:
@Output()
change: EventEmitter<MatCheckboxChange>
Event emitted when the checkbox's checked value changes.
通过这样做,这应该摆脱你的错误。
如果没有,你仍然可以尝试用超时包裹你的模态开头:
setTimeout(() => this.modalService.open<SomeModalComponent>(SomeModalComponent));
答案 1 :(得分:0)
使用detectChanges():
controle.valueChanges.subscribe(value => {
if (value === 'SOME_EQUALS') {
this.modalService.open < SomeModalComponent > (SomeModalComponent);
}
}).add(() => {
this.cd.detectChanges();
});
答案 2 :(得分:0)
我有完全相同的问题(使用 Angular 9)。在没有完全理解潜在问题的情况下,我找到了一个相对简单的解决方案: 您可以在打开模态之前手动将表单字段标记为已触摸:
controle.valueChanges.subscribe(value => {
if (value === 'SOME_EQUALS') {
this.controle.markAsTouched(); // to prevent ExpressionChangedAfterItHasBeenCheckedError
this.modalService.open<SomeModalComponent>(SomeModalComponent);
}
});