14

我有一个父组件,我正在使用 @ViewChild() 将一些 HTML 从它传递给一个子公共组件。

当子组件加载弹出窗口时。控制台抛出以下错误。

“ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后发生了变化。以前的值:'ngIf:undefined'。当前值:'ngIf:这是描述'。看起来视图是在其父级及其子级经过脏检查后创建的。它是在变更检测钩子中创建的吗?”

我正在使用来自 '@ng-bootstrap/ng-bootstrap' 的 { NgbModal };

这是代码。

更新 - 此父组件在另一个父 html 文件中称为 app-parent-component。

父组件

@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';

父 HTML

<ng-template #templateToLoad>
  <div class="someClass">This data will be shown on Popup without any error.
  </div>
</ng-template>

CommonChildPopup 组件

@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');
}

CommonChildPopup 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"。如果我删除这一行,下一行也会出现同样的错误。请帮忙。

4

3 回答 3

19

您正在尝试更新生命周期挂钩中的属性值,此前它们已在父组件中检查过。

推荐的解决方案是在按钮单击/另一个用户触发事件时打开模式,或者如果您需要在视图初始化后打开它,您可以使用 setTimeout() 将跳过一个刻度

ngAfterViewInit() { setTimeout(() => this.openPopup()); }

工作插件:https : //plnkr.co/edit/FVV7QVp620lIGJwEhN6V ?p=preview

关于这个错误的一个非常好的和详细的解释:https ://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

于 2018-03-15T07:29:25.967 回答
12

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'
  });
}
于 2019-02-28T06:46:12.390 回答
8

就我而言,错误发生在 Angular 4 应用程序中。当用户从反应形式的下拉列表中选择一个值时,应用程序需要打开一个 ng-bootrap 模式。使用setTimeout变通方法不起作用。但是,以下链接中描述的解决方案 - 即将控件设置为已触摸(通过调用markAsTouched()控件)解决了该错误。

这个问题在 Angular 中,如此所述。

于 2018-10-04T16:13:04.087 回答