代码之家  ›  专栏  ›  技术社区  ›  Aakash Kumar

表达式已更改打开组件内的模式弹出窗口时出错

  •  14
  • Aakash Kumar  · 技术社区  · 6 年前

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

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

    “ExpressionChangedFederathasBeenCheckedError:表达式在检查后已更改。以前的值:'ngIf:undefined'。当前值:'ngIf:this is description'。该视图似乎是在对其父视图及其子视图进行脏检后创建的。它是在更改检测挂钩中创建的吗?”

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

    这是代码。

    更新- 此父组件在另一个父html文件中称为应用父组件。

    父组件

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

    3 回复  |  直到 6 年前
        1
  •  19
  •   Lucian Moldovan    6 年前

    您正在尝试更新生命周期挂钩中的属性值,之前已在父组件中检查这些属性值。

    建议的解决方案是在按钮单击/另一个用户触发的事件上打开模式,或者如果需要在视图初始化后打开它,可以使用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

        2
  •  12
  •   Arul    5 年前

    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'
      });
    }
    
        3
  •  8
  •   Atif Majeed    6 年前

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

    如前所述,此问题是角度问题 here