角度模型驱动表单 - 双向数据绑定

时间:2017-08-21 19:48:51

标签: javascript angular data-binding angular2-forms

模型驱动表单如何用于初始化控件的值,并绑定到底层数据模型?

我在Angular 2中使用单个模型驱动表单created a Plunker。有四个输入控件:controlAcontrolBcontrolC和{{1 }}:

controlD

所有输入控件都属于同名<form novalidate [formGroup]="form"> <input mdInput placeholder="A" formControlName="controlA"> <input mdInput placeholder="B" formControlName="controlB" [value]="data.B"> <input mdInput placeholder="C" formControlName="controlC" (input)="data.C = $event.target.value"> <input mdInput placeholder="D" formControlName="controlD" [(ngModel)]="data.D"> </form> FormGroup,但它们各自采用不同的数据绑定方法。

  • controlA - 仅使用form
  • controlB - 使用FormControlName并直接从基础模式获取值。
  • controlC - 使用FormControlName并直接更新模型。
  • controlD - 使用FormControlName和双向数据绑定语法。

该组件定义FormControlName,从createForm()调用以创建模型驱动表单:

ngOnInit()

绑定的底层模型是一个简单的Java 具有四个属性的脚本对象,每个输入控件一个:

export class Tree implements OnInit {

  data = {
    A: 'Data A',
    B: 'Data B',
    C: 'Data C',
    D: 'Data D',
  };

  form: FormGroup;

  constructor(private _fb: FormBuilder) {}

  ngOnInit() {
      this.createForm();
  }

  private createForm() {
    const suffix = ' createForm()';

    this.form = this._fb.group({
            controlA: [{value: this.data.A + suffix, disabled: false}],
            controlB: [{value: this.data.B + suffix, disabled: false}],
            controlC: [{value: this.data.C + suffix, disabled: false}],
            controlD: [{value: this.data.D + suffix, disabled: false}],
    });
  }

}

Model Driven表单使用底层模型初始化每个表单控件,但是当控件显示来自底层模型或表单组的数据时,它会添加后缀 data = { A: 'Data A', B: 'Data B', C: 'Data C', D: 'Data D', }; 以使其显而易见。

createForm()

首先要注意的是,只有A和C显示来自FormGroup,B和D的数据显示来自主机元素上声明的绑定的数据。

enter image description here

接下来要注意的是,只有控件C和D再次更新模型,因为在主机元素上声明了绑定。

我想使用表单组初始化输入控件,并将该值写回底层模型。

我的示例中实现此目的的唯一配置是控件C.它从控件组初始化并更新模型:

enter image description here

此时我想,我一定是出错了。当然,使用FormGroup初始化并更新底层模型有一种更简单,更好的定义方法吗?

解决方案#1

使用与ngModel的双向绑定:

  private createForm() {
    const suffix = ' createForm()';

    this.form = this._fb.group({
            controlA: [{value: this.data.A + suffix, disabled: false}],
            controlB: [{value: this.data.B + suffix, disabled: false}],
            controlC: [{value: this.data.C + suffix, disabled: false}],
            controlD: [{value: this.data.D + suffix, disabled: false}],
    });

这里的问题是<input mdInput placeholder="D" formControlName="controlD" [(ngModel)]="data.D"> 只提供表单控件的句柄。没有必要设置值,因为值来自模型,假设不需要FormBuilderValidators 几乎毫无意义。

FormBuilder

解决方案2

感谢@ harry-ninh评论订阅this.form = this._fb.group({ controlD: [] }); 并从更改流中更新模式。虽然这可以用于少量的表单控件 - 如果我有一个非常大的表单,可能有数百个控件,这是因为无法管理。

目前我要离开解决方案#1 - 只需使用FormGroup.valueChanges获取组件中表单的句柄,添加使用FormGroup来设置输入值和更新模型

虽然感觉还不好。

0 个答案:

没有答案