在组件内打开模态弹出窗口时表达式已更改错误
Expression has changed error on Opening a Modal Popup inside a component
我有一个 parent 组件,我正在使用 @ViewChild() 将一些 HTML 从它传递到 child 公共组件。
当 Child 组件加载弹出窗口时。控制台抛出以下错误。
"ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: undefined'. Current value: 'ngIf: this is description'. It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook ?"
我正在使用来自'@ng-bootstrap/ng-bootstrap'的{NgbModal};
这是代码。
更新-
此 parent 组件在另一个 parent html 文件中称为 app-parent-component。
Parent 组件
@ViewChild('templateToLoad') templateToLoad;
constructor(private modalService: NgbModal, private ChangeDetector: ChangeDetectorRef) {
}
ngOnInit() {
this.openPopup();
}
ngAfterViewInit() {
this.ChangeDetector.detectChanges();
}
private openPopup() {
const modalPrompt = this.modalService.open(CommonChildModalComponent, {windowClass: 'modal-prompt fade-in-down'});
modalPrompt.componentInstance.title = 'Title';
modalPrompt.componentInstance.contentTemplate = this.templateToLoad;
modalPrompt.componentInstance.originContext = this;
modalPrompt.componentInstance.description = 'ABC';
Parent HTML
<ng-template #templateToLoad>
<div class="someClass">This data will be shown on Popup without any error.
</div>
</ng-template>
普通Child弹窗组件
@Input() title?: string;
@Input() description?: string;
@Input() originContext: any;
@Input() contentTemplate?: any;
constructor(public activeModal: NgbActiveModal) {
}
ngOnInit() {
console.log('I am here in CommonModalComponent ngOnInit');
}
普通Child弹出HTML
<div class="modal-header">
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body pb-3" [class.dimmer]="simulateLoading">
<p *ngIf="description">{{description}}</p>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
上面的控制台错误是针对这一行 ngIf="description"。如果我删除这一行,下一行将出现同样的错误。请帮忙。
您正在尝试更新生命周期挂钩中的 属性 值,此前它们已在父组件中检查过。
推荐的解决方案是在单击按钮/另一个用户触发的事件时打开模式,或者如果您需要在视图初始化后打开它,您可以使用 setTimeout() 来跳过一个滴答
ngAfterViewInit() {
setTimeout(() => this.openPopup());
}
工作 plunker : https://plnkr.co/edit/FVV7QVp620lIGJwEhN6V?p=preview
在我的例子中,错误发生在 Angular 4 应用程序中。当用户以反应形式从下拉列表中选择一个值时,应用程序需要打开一个 ng-bootrap 模式。使用 setTimeout
解决方法无效。但是,下面 link 中描述的解决方案——即将控件设置为已触摸(通过在控件上调用 markAsTouched()
)解决了错误。
如 here 所述,此问题在 Angular 中。
ExpressionChangedAfterItHasBeenCheckedError
: 检查后表达式发生了变化。以前的值:'ng-untouched: true'
。当前值:'ng-untouched: false'
.
setTimeout
技巧也不适用于订阅反应形式。以下解决方法应该对我有用
html
<select [ngModel]="countryId" #ngModelDir="ngModel"
(ngModelChange)="fileChangeEvent($event, ngModelDir)">
ts
import { NgModel } from '@angular/forms';
...
fileChangeEvent(event: any, ngModelDir: NgModel) {
ngModelDir.control.markAsTouched();
const modalRef = this.modalService.open(MymodalComponent, {
keyboard: false,
backdrop: 'static'
});
}
我有一个 parent 组件,我正在使用 @ViewChild() 将一些 HTML 从它传递到 child 公共组件。
当 Child 组件加载弹出窗口时。控制台抛出以下错误。
"ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: undefined'. Current value: 'ngIf: this is description'. It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook ?"
我正在使用来自'@ng-bootstrap/ng-bootstrap'的{NgbModal};
这是代码。
更新- 此 parent 组件在另一个 parent html 文件中称为 app-parent-component。
Parent 组件
@ViewChild('templateToLoad') templateToLoad;
constructor(private modalService: NgbModal, private ChangeDetector: ChangeDetectorRef) {
}
ngOnInit() {
this.openPopup();
}
ngAfterViewInit() {
this.ChangeDetector.detectChanges();
}
private openPopup() {
const modalPrompt = this.modalService.open(CommonChildModalComponent, {windowClass: 'modal-prompt fade-in-down'});
modalPrompt.componentInstance.title = 'Title';
modalPrompt.componentInstance.contentTemplate = this.templateToLoad;
modalPrompt.componentInstance.originContext = this;
modalPrompt.componentInstance.description = 'ABC';
Parent HTML
<ng-template #templateToLoad>
<div class="someClass">This data will be shown on Popup without any error.
</div>
</ng-template>
普通Child弹窗组件
@Input() title?: string;
@Input() description?: string;
@Input() originContext: any;
@Input() contentTemplate?: any;
constructor(public activeModal: NgbActiveModal) {
}
ngOnInit() {
console.log('I am here in CommonModalComponent ngOnInit');
}
普通Child弹出HTML
<div class="modal-header">
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body pb-3" [class.dimmer]="simulateLoading">
<p *ngIf="description">{{description}}</p>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
上面的控制台错误是针对这一行 ngIf="description"。如果我删除这一行,下一行将出现同样的错误。请帮忙。
您正在尝试更新生命周期挂钩中的 属性 值,此前它们已在父组件中检查过。
推荐的解决方案是在单击按钮/另一个用户触发的事件时打开模式,或者如果您需要在视图初始化后打开它,您可以使用 setTimeout() 来跳过一个滴答
ngAfterViewInit() {
setTimeout(() => this.openPopup());
}
工作 plunker : https://plnkr.co/edit/FVV7QVp620lIGJwEhN6V?p=preview
在我的例子中,错误发生在 Angular 4 应用程序中。当用户以反应形式从下拉列表中选择一个值时,应用程序需要打开一个 ng-bootrap 模式。使用 setTimeout
解决方法无效。但是,下面 link 中描述的解决方案——即将控件设置为已触摸(通过在控件上调用 markAsTouched()
)解决了错误。
如 here 所述,此问题在 Angular 中。
ExpressionChangedAfterItHasBeenCheckedError
: 检查后表达式发生了变化。以前的值:'ng-untouched: true'
。当前值:'ng-untouched: false'
.
setTimeout
技巧也不适用于订阅反应形式。以下解决方法应该对我有用
html
<select [ngModel]="countryId" #ngModelDir="ngModel"
(ngModelChange)="fileChangeEvent($event, ngModelDir)">
ts
import { NgModel } from '@angular/forms';
...
fileChangeEvent(event: any, ngModelDir: NgModel) {
ngModelDir.control.markAsTouched();
const modalRef = this.modalService.open(MymodalComponent, {
keyboard: false,
backdrop: 'static'
});
}