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

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

表单提交后,我登出这个。表格栏还是空白!我见过其他人使用updateValue(),但这是测试版。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>

当前回答

更新:19/03/2017

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

OLD:

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

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

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

其他回答

我知道答案已经给出了,但我想给出一个简短的答案如何更新表单的值,以便其他新来者可以得到一个清晰的想法。

你的表单结构是如此完美,可以用它作为一个例子。因此,在我的回答中,我将把它称为形式。

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

当您需要更新表单控件时,只需使用该属性来更新它。在本例中,提问者试图在用户从下拉列表中选择项目时更新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参见这里

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

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

更新:19/03/2017

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

OLD:

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

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

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

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

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

提示:如果你使用setValue,但没有提供表单上的每个属性,你会得到一个错误:

必须为名称为“stateOrProvince”的表单控件提供一个值。

因此,您可能想要使用patchValue,但如果您试图更新整个表单,这可能是危险的。我的地址可能没有state或province或stateCd,这取决于它是美国还是全球。

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

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