手动设置FormBuilder控件的值

时间:2016-01-27 14:09:09

标签: forms components angular

这让我疯了,我已经掏了枪,无法再花上一整天的时间。

我正在尝试在组件中手动设置一个控制值(' dept'),它只是不起作用 - 即使是新值也会正确地登录到控制台。

这是FormBuilder实例:

initForm() {
  this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required],
  });
}

这是接收选定部门的事件处理程序:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].value = selected.id;
}

现在提交表单并且我退出this.form时,该字段仍为空白!我已经看到其他人使用updateValue(),但这是beta.1,我不认为这是调用控件的有效方法。

我还试图致电updateValueAndValidity()但没有成功:(。

我只会在表单元素上使用ngControl="dept",就像我正在处理表单的其余部分,但它是自定义指令/组件。

<ng-select
  [data]="dept"
  [multiple]="false"
  [items]="depts"
  (selected)="deptSelected($event)" <!-- This is how the value gets to me -->
  [placeholder]="'No Dept Selected'"></ng-select>

11 个答案:

答案 0 :(得分:224)

更新日期:19/03/2017

this.form.controls['dept'].setValue(selected.id);

<强> OLD:

现在我们被迫做一个类型转换:

(<Control>this.form.controls['dept']).updateValue(selected.id)

我同意不是很优雅。希望在未来的版本中有所改进。

答案 1 :(得分:88)

在Angular 2 Final(RC5 +)中,有用于更新表单值的新API。 patchValue() API方法支持部分表单更新,我们只需要指定一些字段:

this.form.patchValue({id: selected.id})

还有setValue() API方法需要一个包含所有表单字段的对象。如果缺少某个字段,我们将收到错误。

答案 2 :(得分:15)

Aangular 2 final已更新API。他们为此添加了许多方法。

要从控制器更新表单控件,请执行以下操作:

this.form.controls['dept'].setValue(selected.id);

this.form.controls['dept'].patchValue(selected.id);

无需重置错误

参考

https://angular.io/docs/ts/latest/api/forms/index/FormControl-class.html

https://toddmotto.com/angular-2-form-controls-patch-value-set-value

答案 3 :(得分:9)

你可以试试这个:

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // This is how I am trying to set the value
  this.form.controls['dept'].updateValue(selected.id);
}

有关详细信息,您可以查看有关updateValue方法的第二个参数的相应JS文档:https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model.ts#L269

答案 4 :(得分:7)

如果您使用表单控件,则最简单的方法是:

this.FormName.get('ControlName').setValue(value);

答案 5 :(得分:4)

您可以使用以下方法来更新反应形式控件的值。以下任何一种方法都可以满足您的需求。

使用setValue()的方法

this.form.get("dept").setValue(selected.id);
this.form.controls["dept"].setValue(selected.id);

使用patchValue()的方法

this.form.get("dept").patchValue(selected.id);
this.form.controls['dept'].patchValue(selected.id);
this.form.patchValue({"dept": selected.id});

Last方法将循环遍历表单中的所有控件,因此在更新单个控件时不是首选

您可以在事件处理程序中使用任何方法

deptSelected(selected: { id: string; text: string }) {
     // any of the above method can be added here
}

如果需要,您可以使用

更新表单组中的多个控件。
this.form.patchValue({"dept": selected.id, "description":"description value"});

答案 6 :(得分:3)

  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);

如果您不想手动设置每个字段。

答案 7 :(得分:3)

这些都不适合我。我不得不这样做:

  this.myForm.get('myVal').setValue(val);

答案 8 :(得分:2)

@Filoche的Angular 2更新解决方案。使用FormControl

<击> (<Control>this.form.controls['dept']).updateValue(selected.id)

import { FormControl } from '@angular/forms';

(<FormControl>this.form.controls['dept']).setValue(selected.id));

或者您可以使用@ AngularUniversity solution使用patchValue

答案 9 :(得分:0)

我知道答案已经给出,但是我想给出一个简短的答案,说明如何更新表单的值,以便其他新手可以清楚地了解主意。

您的表单结构非常适合用作示例。因此,在整个回答中,我将其表示为表格。

this.form = this.fb.group({
    'name': ['', Validators.required],
    'dept': ['', Validators.required],
    'description': ['', Validators.required]
  });

所以我们的表单是具有三个 FormControl 的对象的 FormGroup 类型。

  

有两种方法可以更新模型值:

     
      
  • 使用setValue()方法为单个控件设置新值。 setValue()方法严格遵守   表单组并替换控件的整个值。

  •   
  • 使用patchValue()方法来替换对象中定义的属性,这些属性在表单模型中已更改。

  •   
     

对setValue()方法的严格检查有助于捕获嵌套错误   以复杂的形式出现,而patchValue()在出现这些错误时会自动失败。

     

摘自Angular官方文档 here

因此,当更新包含多个控件的表单组实例的值时,但是您可能只想更新模型的某些部分。 patchValue()是您要寻找的。

请参见示例。当您使用 patchValue()

this.form.patchValue({
    dept: 1 
});
//here we are just updating only dept field and it will work.

但是,当您使用 setValue()时,您需要更新完整模型,因为它严格遵守表单组的结构。 所以,如果我们写

this.form.setValue({
    dept: 1 
});
// it will throw error.

我们必须传递表单组模型的所有属性。像这样

this.form.setValue({
      name: 'Mr. Bean'
      dept: 1,
      description: 'spome description'
  });

但是我不经常使用这种样式。我更喜欢使用以下方法来帮助使我的代码更加整洁和易于理解。

我要做的是,将所有控件声明为一个单独的变量,然后使用setValue()更新该特定控件。

对于上面的表格,我将做类似的事情。

get companyIdentifier(): FormControl {
    return this.form.get('name') as FormControl;
}

get dept(): FormControl {
    return this.form.get('dept') as FormControl;
}

get description(): FormControl {
    return this.form.get('description') as FormControl;
}

当您需要更新表单控件时,只需使用该属性即可对其进行更新。在该示例中,当用户从下拉列表中选择一项时,发问者尝试更新部门表单控件。

deptSelected(selected: { id: string; text: string }) {
  console.log(selected) // Shows proper selection!

  // instead of using this.form.controls['dept'].setValue(selected.id), I prefer the following.

  this.dept.setValue(selected.id); // this.dept is the property that returns the 'dept' FormControl of the form.
}

我建议看看FormGroup API,以了解FormGroup的所有属性和方法。

其他:了解 getter 的信息,请参见here

答案 10 :(得分:-1)

提示:如果您使用的是setValue,但没有在表单上提供每个属性,则会收到错误消息:

Must supply a value for form control with name: 'stateOrProvince'.

因此,您可能会想使用patchValue,但是如果您要更新整个表单,这可能很危险。我有一个address可能没有stateOrProvincestateCd,具体取决于它是美国还是全世界。

相反,您可以像这样进行更新-它将使用null作为默认值:

this.form.setValue( { stateOrProvince: null, stateCd: null, ...address } );