angular - ExpressionChangedAfterItHasBeenCheckedError: Expr 在检查后已更改。上一个值:'ngIf: false'。当前值:'ngIf: true'
问题描述
我正在使用 Angular 7 并使用“ng serve”来启动应用程序。我有父子组件,父组件有一个点击按钮,可以翻转一个布尔属性值。如果该布尔属性为真,则显示子组件 (*ngIf)。从子组件中,我发出一个事件,该事件调用父级中的函数,该函数翻转父级中的布尔属性值,导致子组件被删除 (*ngIf)
父组件:
父组件.ts
capture: boolean = false;
onCapture () {
console.log("onCapture called")
this.capture = !this.capture;
}
Parent.component.html
<app-capture *ngIf="capture ==true" (closeCapturePage)="onCapture()"></app-capture>
<label>
<img src="/assets/img/camera.svg" alt="" width="32" height="32" title="Open window">
<input type="button" (click)="onCapture()" id="capture" style="display: none">
</label>
子组件.ts
@Output() closeCapturePage = new EventEmitter<void>();
closePage() {
this.closeCapturePage.emit();
}
我可以看到子组件成功发出事件但是遇到错误 ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it is checked。以前的值:'ngIf: false'。当前值:'ngIf: true'
我尝试了类似线程中建议的解决方案,例如在父组件中实现 ngAfterViewChecked 但没有运气。
show = false;
ngAfterViewChecked(): void {
let show = this.capture;
if (show != this.show) {
this.show = show;
this.cdRef.detectChanges();
}
}
Stackblitz 示例:https ://stackblitz.com/edit/angular-8efhdm (注意:简单的示例没有复制,所以我添加了启动相机但不记录任何内容的实际代码,没有隐私问题!)
解决方案
以防万一有人像我一样寻找答案。我需要的解决方案是了解错误的原因:
https://indepth.dev/posts/1001/everything-you-need-to-know-about-the-expressionchang
当我知道正在发生变化时,将应用这段代码。
由于这个 HTML 代码,我收到了 expressChangedAfterChecked
<relation-mapping *ngIf="loadRelationMappings"
[mappingPayload]="mappingPayload"
[mappedRelationIndex]="mappedRelationIndex"
(mappingPayloadEmitted)="onSentMappingPayload($event)"
(mappedRelationIndexEmitted)="onSentRelationIndex($event)"
></relation-mapping>
异步调用后的这个变化
this.LS.findAll('MappingPart2', 'master').subscribe( (mappingData: Collection) => {
console.log('mappingData', mappingData);
console.log('targetEntity', this.targetEntity);
// find if class has mappings
const list = mappingData._items.filter( (lc: Lifecycle) => lc._mapping._clazzReference._name === this.ES.targetNodePath[1].data.name);
this.mappingPayload = list.length === 1 ? list[0] : null;
// find if the class has a mapping for the relation the user is on
if (!!this.mappingPayload) {
this.loadRelationMappings = true;
this.mappedRelationIndex = this.mappingPayload._mapping._mappedRelations.findIndex( (relationMapped: RelationMap) => relationMapped._name === this.ES.targetEntity._name);
this.cd.detectChanges();
if (this.mappedRelationIndex !== -1 ) {
this.readRelations = this.mappingPayload._mapping._mappedRelations[this.mappedRelationIndex]._mappedRelationMappings;
}
}
console.log('this.targetMapping', this.mappingPayload);
});
当我知道变量/值正在更新时添加 this.cd.detectChanges() 为我解决了这个问题。
推荐阅读
- android - InstallReferrerReceiver 在实时应用程序中不起作用
- runtime - Hasura:通过 API 调用在运行时(动态)更改 Hasura 中的权限/模式
- typescript - Application Insights TrackEvent 从未在 Azure 中保留
- firebase - 从两台计算机使用 firebase 服务
- php - 如何从 laravel 中的数据透视表中制作可靠的下拉菜单
- r - 在 dplyr 1.0 中重命名 tidyeval 中的列
- c# - Wpf .Net.5 应用程序中的 Prism 和 Uno 平台。使用什么 Nuget 包?
- java - 如何将存储在字符串数组中的特定字符串打印到字符串数组的 ArrayList 中?
- php - Symfony 中的路径类型:何时使用“AppBundle:SomeEntity”或“AppBundle/Entity/SomeEntity”?
- eclipse - 如何诱使 Eclipse 显示缺少的 @Nullable/@NonNull “注释”命令?