Angular: formArray 添加项和表单 valueChange

Angular: formArray add item and form valueChange

我有一个使用 formArray 的表单:

  initForm() {
    this.mainForm = this.formBuilder.group({
      foos: this.formBuilder.array([], [Validators.required]),
    });
    
  getFoos(): FormArray {
    return this.mainForm.get('foos') as FormArray;
  }

  onAddFoo() {
    this.getFoos().push(this.formBuilder.control(''));
  }

Foo 项是一个子窗体:

export interface FooFormValues {
    id: number,
    toto: number,
}

@Component({
  selector: 'ngx-Foo',
  templateUrl: './Foo.component.html',
  styleUrls: ['./Foo.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => FooComponent),
      multi: true
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => FooComponent),
      multi: true
    }
  ]
})
export class FooComponent implements OnInit, OnDestroy, ControlValueAccessor {

  @Input() inErrors: any[];

  destroy$: Subject<boolean> = new Subject<boolean>();
    
  FooForm: FormGroup;

  constructor(
    private formBuilder: FormBuilder,
    public translate: TranslateService,
    ) { 
    }

  get f() { return this.FooForm.controls; }

/////////////////////////////////////////////////////////
////// OnInit & onDestroy
/////////////////////////////////////////////////////////
  ngOnInit(): void {
        this.initForm();
        this.FooForm.valueChanges.takeUntil(this.destroy$).subscribe(value => {
            this.onChange(value);
            this.onTouched();
        });
        
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
  }

//////////////////////////////////////////////////////////////////////////////
///// Control Value Accessor
//////////////////////////////////////////////////////////////////////////////

  get value(): FooFormValues {
    return this.FooForm.value;
  }

  set value(value: FooFormValues) {
    //if( value !== undefined && this.value !== value){ 
    if( value !== undefined ){      
        this.FooForm.patchValue(value);
        this.onChange(value);
        this.onTouched();
    }
  }

  onChange: any = () => {}

  onTouched: any = () => {
  }

  // this method sets the value programmatically
  writeValue(value) {
    if (value) {
        this.value = value;
    }

    if (value === null) {
      this.FooForm.reset();
    }

  }

// upon UI element value changes, this method gets triggered
  registerOnChange(fn) {
    this.onChange = fn;
  }

// upon touching the element, this method gets triggered
  registerOnTouched(fn) {
    this.onTouched = fn;
  }

  // communicate the inner form validation to the parent form
  validate(_: FormControl) {
    return this.FooForm.valid ? null : { profile: { valid: false } };
  }

  get errors() {
    return this.FooForm.errors ? null : this.FooForm.errors;
  }


//////////////////////////////////////////////////////////////////////////////
///// Miscellaneous Functions
//////////////////////////////////////////////////////////////////////////////

  initForm() {
    this.FooForm = this.formBuilder.group({
        id: '',
        toto: ['10', [Validators.required, Validators.min(0)]],
    });
  }

  onSubmitForm() {}

}

我的主要表单组件使用对 valueChange 的订阅:

this.mainForm.valueChanges.takeUntil(this.destroy$).subscribe(val => {...});

当点击添加 formArray 项按钮时,主窗体的 onChange 被触发,但是 val.foos 是 ["",",",...]

I try to add :
    this.value={
        id: null,
        toto: 10,} 

在 InitForm 函数中,但结果相同!

感谢您的帮助

像这样在 ViewInit 之后调用 updateValueandValidity 手动触发 valueChanges 它将更新父 formControl。

试试这个:

ngAfterViewInit(){
    setTimeout(()=>{
      this.FooForm.updateValueAndValidity();
    })
  }

Working Example