手动设置FormBuilder控件的值

Mat*_*own 142 forms components angular

这让我疯了,我在枪下,无法再花上一整天的时间.

我试图在组件中手动设置一个控制值('dept'),它只是不工作 - 甚至新值记录到控制台正常.

这是FormBuilder实例:

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

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

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;
}
Run Code Online (Sandbox Code Playgroud)

现在,当表单提交并且我注销时,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>
Run Code Online (Sandbox Code Playgroud)

小智 272

更新时间:2017年3月19日

this.form.controls['dept'].setValue(selected.id);
Run Code Online (Sandbox Code Playgroud)

旧:

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

(<Control>this.form.controls['dept']).updateValue(selected.id)
Run Code Online (Sandbox Code Playgroud)

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

  • 或者`this.form.get('dept').setValue(selected.id)`:) (13认同)
  • 这很好用,谢谢.还需要清除验证:`(<Control> this.form.controls ['dept']).setErrors(null)` (6认同)
  • 请注意。您也可以不使用索引器直接访问属性。`this.form.controls.dept.setValue(selected.id);` (5认同)
  • 对我来说这是 2019 年:`this.form.controls['dept'].setValue(selected.id);` (2认同)

Ang*_*ity 92

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

this.form.patchValue({id: selected.id})
Run Code Online (Sandbox Code Playgroud)

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

  • 只是补充说,截至目前`updateValue`(来自Filoche的接受答案)正在被弃用,转而支持`setValue` (7认同)
  • 这是Github上的[官方拉取请求](https://github.com/angular/angular/pull/10537)以及弃用`updateValue()`和引入`patchValue`和`setValue`的基本原理. (2认同)

tan*_*dar 15

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

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

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

this.form.controls['dept'].patchValue(selected.id);
Run Code Online (Sandbox Code Playgroud)

无需重置错误

参考

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

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


Thi*_*ier 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);
}
Run Code Online (Sandbox Code Playgroud)

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


Rai*_*doy 9

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

this.FormName.get('ControlName').setValue(value);
Run Code Online (Sandbox Code Playgroud)


viv*_*ien 8

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

使用setValue()的方法

this.form.get("dept").setValue(selected.id);
this.form.controls["dept"].setValue(selected.id);
Run Code Online (Sandbox Code Playgroud)

使用patchValue()的方法

this.form.get("dept").patchValue(selected.id);
this.form.controls['dept'].patchValue(selected.id);
this.form.patchValue({"dept": selected.id});
Run Code Online (Sandbox Code Playgroud)

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

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

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

您可以根据需要使用以下方式更新表单组中的多个控件:

this.form.patchValue({"dept": selected.id, "description":"description value"});
Run Code Online (Sandbox Code Playgroud)


cho*_*ovy 6

这些都不适合我。我必须做:

  this.myForm.get('myVal').setValue(val);
Run Code Online (Sandbox Code Playgroud)


Sad*_*han 6

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

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

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

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

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

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

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

setValue() 方法的严格检查有助于捕获复杂形式的嵌套错误,而 patchValue() 会在这些错误上静默失败。

来自 此处的Angular 官方文档

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

让我们看看例子。当您使用patchValue()

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

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

this.form.setValue({
    dept: 1 
});
// it will throw error.
Run Code Online (Sandbox Code Playgroud)

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

this.form.setValue({
      name: 'Mr. Bean'
      dept: 1,
      description: 'spome description'
  });
Run Code Online (Sandbox Code Playgroud)

但我不经常使用这种风格。我更喜欢使用以下方法来帮助保持我的代码更清晰、更易于理解。

我所做的是,我将所有控件声明为一个单独的变量,并使用 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;
}
Run Code Online (Sandbox Code Playgroud)

当您需要更新表单控件时,只需使用该属性来更新它。在这个例子中,当用户从下拉列表中选择一个项目时,提问者试图更新部门表单控件。

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.
}
Run Code Online (Sandbox Code Playgroud)

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

附加:要了解getter,请参见此处


rob*_*xes 5

  let cloneObj = Object.assign({}, this.form.getRawValue(), someClass);
  this.form.complexForm.patchValue(cloneObj);
Run Code Online (Sandbox Code Playgroud)

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