Angular: formArray добавить элемент и сформировать значениеChange

У меня есть форма, которая использует 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() {}

}

Мой основной компонент Form использует подписку на valueChange :

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

При нажатии кнопки добавления элемента formArray запускается основная форма onChange, но val.foos имеет значение [,,...]

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

в функции InitForm, но тот же результат!

спасибо за помощь


person Alexglvr    schedule 23.07.2020    source источник


Ответы (1)


Запустите valueChanges вручную, вызвав updateValueandValidity после ViewInit, таким образом, он обновит родительский formControl.

Попробуйте это:

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

Рабочий пример

person Chellappan வ    schedule 23.07.2020