手动设置 FormBuilder 控件的值

Manually Set Value for FormBuilder Control

这快把我逼疯了,我身陷囹圄,不能再花一整天在这上面。

我正在尝试在组件中手动设置一个控制值 ('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",就像我对表单的其余部分所做的那样,但它是自定义的 directive/component.

<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>

你可以试试这个:

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.

更新时间:2017 年 3 月 19 日

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

旧:

现在我们被迫进行类型转换:

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

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

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

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

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

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

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

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

@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));

或者你可以使用@Angular大学的,它使用patchValue

None 其中对我有用。我必须做的:

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

您可以使用以下方法更新反应式表单控件的值。以下任何一种方法都适合您的需要。

使用 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});

最后一种方法将遍历表单中的所有控件,因此在更新单个控件时不是首选方法

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

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

如果需要,您可以使用

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

提示: 如果您使用 setValue 但未在表格中提供 every 属性会报错:

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

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

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

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

我知道答案已经给出了,但我想简要回答一下如何更新表单的值,以便其他新手可以清楚地了解。

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

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

所以我们的表单是一个 FormGroup 类型的对象,它有三个 FormControl.

There are two ways to update the model value:

  • Use the setValue() method to set a new value for an individual control. The setValue() method strictly adheres to the structure of the form group and replaces the entire value for the control.

  • Use the patchValue() method to replace any properties defined in the object that have changed in the form model.

The strict checks of the setValue() method help catch nesting errors in complex forms, while patchValue() fails silently on those errors.

From Angular official documentation 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;
}

当您需要更新表单控件时,只需使用 属性 来更新它。在示例中,提问者试图在用户 select 下拉列表中的项目时更新部门表单控件。

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

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

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