簡體   English   中英

角度:ExpressionChangedAfterItHasBeenCheckedError子組件和FormControl

[英]Angular: ExpressionChangedAfterItHasBeenCheckedError child component & FormControl

我已經閱讀,閱讀並嘗試了許多有關此主題的問題,答案和博客。 我了解代碼中為什么會發生這種情況,但我只是不知道如何解決。

(簡化實際代碼;如果我犯了錯誤或忘記了重要的事情,請在評論中讓我知道)

我有一個帶有輸入的父組件A和一個子組件B。

<form [formgroup]="modalForm">
   <input type="text" formControlName="text"></input>
   <componentB 
    [formControl]="modalForm.controls['componentB'] 
    [firstProperty]="foo" 
    [secondProperty]="bar">
   </componentB>
</form>

ComponentB也有一個輸入和一個自定義消息組件:

<div>
   <input type="text" [formControl]="formControl"></input>
   <message
    [message]="firstProperty" 
    [secondMessage]="secondProperty">
   </message>
</div>

ComponentA:

export class ComponentA implements OnInit{

  public foo: string;
  public bar: string;
  public modalFrom: FormGroup;

  public constructor(private componentBValidatorFactory: ComponentBValidatorFactory){}

  public ngOnInit(): void {
    this.modalForm = new FormGroup({
     text: new FormControl(null),
     componentB: new FormControl(null, {
        validators: Validators.required,
        asyncValidatiors: [this.componentBValidatorFactory.asyncValidatorFn()],
        updateOn: 'blur'
        })
    });
  this.modalForm.controls['text'].valueChanges(subscribe( () => this.textChanged());
  this.modalForm.controls['componentB'].valueChanges(subscribe( () => this.componentBChanged());
  }

  private textChanged(): void {
  this.foo = this.modalForm.controls['text'].value;
  }

  private componentBChanged(): void {
  this.bar = this.modalForm.controls['componentB'].value + 'somestring';
  }
}

ComponentB(簡體):

export class ComponentB{

@Input()
public formControl: FormControl;

@Input()
public firstProperty: string;

@Input()
public secondProperty: string;

}

問題(據我了解):當text更改(用戶輸入)時,它將用值更新foo 這意味着ComponentB發生了變化,因此觸發了ComponentB的valueChanges ComponentBChanged被觸發,並更新bar text再次更改時, bar再次更改,但是由於它與第二次處理foo時的先前值不同,因此我得到了眾所周知的ExpressionChangedAfterItHasBeenCheckedError (盡管正確處理了值)。 據我了解: ComponentB已被更新( foo ),這將觸發同一組件綁定的另一項更改( bar )。 這並不能使Angular開心。 直接將輸入放入ComponentB (也有一個輸入字段)可以正常工作,它可以正確更新bar ,而不會出現問題。

我應該怎么做才能無問題地更新bar 我無法在代碼中更新textChanged中的bar ,因為如果直接操作ComponentB也應該進行更新。

而不是將FormControl傳遞給子Use,然后將foo和bar屬性分配為null

formControlDirective

該指令接受現有的FormGroup實例。 然后,它將使用此FormGroup實例將任何子FormControl,FormGroup和FormArray實例與子FormControlName,FormGroupName和FormArrayName指令匹配。

Parent.component.html

<form [formGroup]="form">
  <label >Text</label>
  <input formControlName="text">
  <app-component-a 
  [firstProperty]="foo" 
    [secondProperty]="bar"
  ></app-component-a>
</form>

APP-組件a.ts

import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, FormControl, ControlContainer, FormGroupDirective, Validators } from '@angular/forms';
@Component({
  selector: 'app-component-a',
  templateUrl: './component-a.component.html',
  styleUrls: ['./component-a.component.css'],
  viewProviders:[{provide: ControlContainer,useExisting:FormGroupDirective}]
})
export class ComponentAComponent implements OnInit {

 @Input('firstProperty') firstProperty:string;
 @Input('secondProperty') secondProperty:string;

  constructor(private fgd:FormGroupDirective) { 

  }

  ngOnInit() {
    this.fgd.form.addControl('componentA',new FormControl('',{updateOn: 'blur'}))
  }

}

示例: https//stackblitz.com/edit/angular-65nmvr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM