手动设置FormBuilder控件的值

这快把我逼疯了,我压力很大,不能在这上面再耗上一整天。

我试图在组件内手动设置一个控制值('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>
485834 次浏览

你可以试试这个:

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方法的第二个参数:https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model.ts#L269的相应JS文档。

更新:19/03/2017

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

旧:

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

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

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

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

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

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

Aangular 2最终版更新了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));

或者你也可以使用@AngularUniversity的解决方案,它使用patchValue

这些对我都没用。我必须这么做:

  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,但没有在表单上提供每一个属性,你会得到一个错误:

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. c。

有两种方法来更新模型值:

  • 使用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.

但是当你使用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;
}

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

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,请参阅在这里

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

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