角度形式:每个单独控件的值变化

Wou*_*tte 6 angular angular-forms

我想听我的表单的值更改,但不是整个表单,而是仅针对已更改的表单控件。

例如,如果我的表格看起来像这样。

this.form = this._fb.group({
  firstName: [''],
  lastName: [''],
  ... // other stuff.
});
Run Code Online (Sandbox Code Playgroud)

如果我订阅 valuechanges

this.form.valueChanges.subscribe((e) => {
  console.log(e);
});
Run Code Online (Sandbox Code Playgroud)

然后在表单中填写名字将导致整个表单值对象的打印输出。

{名字:'输入',姓氏:'',...}

但我想知道的是哪个表单控件(在本例中为firstName)在不订阅每个单独的表单控件的情况下被更改。这样我想要的输出只是

{名字:'输入'}

And*_*tej 5

首先,多个AbstractControls(例如FormControl, FormGroupFormArray)在内部存储为树。

// FG - FormGroup
// FA - FormArray
// FC - FormControl

    FG
  /   \
FC    FG
    /    \
  FC     FA
        / | \
      FC FC FC
Run Code Online (Sandbox Code Playgroud)

上面的片段摘自《Angular Forms 彻底探索》

因此,当子进程发出FormGroup.valueChanges时, a 也会发出:FormGroupvalueChanges

// FG - FormGroup
// FA - FormArray
// FC - FormControl

    FG
  /   \
FC    FG
    /    \
  FC     FA
        / | \
      FC FC FC
Run Code Online (Sandbox Code Playgroud)

上面的代码片段中,如果我们考虑您的示例,_parent可以参考接收到一些输入this.form FormGroup时的实例。firstName FormControl


因此,实现您正在寻找的目标的一种方法是:

updateValueAndValidity (/* ... */) {
  /* ... */

  if (opts.emitEvent !== false) {
    (this.valueChanges as EventEmitter<any>).emit(this.value);
    (this.statusChanges as EventEmitter<string>).emit(this.status);
  }
  
  if (this._parent && !opts.onlySelf) {
    this._parent.updateValueAndValidity(opts);
  }
  
  /* ... */
}
Run Code Online (Sandbox Code Playgroud)

这个FormGroup.controls签名:

merge(
  ...Object.keys(this.form.controls).map(
    k => this.form.controls[k].valueChanges.pipe(
      // Getting a decent format: `{ formControlName: formControlValue }`
      map(v => ({ [k]: v })),
    )
  )
).subscribe(console.log)
Run Code Online (Sandbox Code Playgroud)