如何在 Angular 的反应式表单中设置表单控件的值
Posted
技术标签:
【中文标题】如何在 Angular 的反应式表单中设置表单控件的值【英文标题】:How to set value to form control in Reactive Forms in Angular 【发布时间】:2019-08-11 23:43:55 【问题描述】:大家好,我是 Angular 的新手。实际上,我正在尝试从服务订阅数据,并且该数据正在传递给我的表单控件(例如,它就像一个编辑表单)。
import Component, OnInit from '@angular/core';
import FormBuilder, FormGroup, Validators, FormArray, FormControl from '@angular/forms';
import ActivatedRoute, Router from '@angular/router';
import QuestionService from '../shared/question.service';
@Component(
selector: 'app-update-que',
templateUrl: './update-que.component.html',
styleUrls: ['./update-que.component.scss']
)
export class UpdateQueComponent implements OnInit
questionsTypes = ['Text Type', 'Multiple choice', 'Single Select'];
selectedQuestionType: string = "";
question: any = ;
constructor(private route: ActivatedRoute, private router: Router,
private qService: QuestionService, private fb: FormBuilder)
ngOnInit()
this.getQuebyid();
getQuebyid()
this.route.params.subscribe(params =>
this.qService.editQue([params['id']]).subscribe(res =>
this.question = res;
);
);
editqueForm = this.fb.group(
user: [''],
questioning: ['', Validators.required],
questionType: ['', Validators.required],
options: new FormArray([])
)
setValue()
this.editqueForm.setValue(user: this.question.user, questioning: this.question.questioning)
如果我在表单字段中使用[(ngModule)]
将值设置为我的元素,它工作正常并显示警告,它将在 Angular 7 版本中被弃用。
<textarea formControlName="questioning" [(ngModule)]="question.questioning" cols="70" rows="4"></textarea>
因此,我通过以下操作将值设置为表单控件,但元素未显示这些值。
setValue()
this.editqueForm.setValue(user: this.question.user, questioning: this.question.questioning)
谁能告诉我如何设置值来挖掘反应形式。请给我建议。
【问题讨论】:
【参考方案1】:可以使用patchValue 和setValue 来设置或更新响应式表单表单控件的值。但是,在某些情况下使用patchValue 可能会更好。
patchValue
不需要在参数中指定所有控件来更新/设置表单控件的值。另一方面,setValue
要求填写所有表单控件值,如果您的任何控件未在参数中指定,它将返回错误。
在这种情况下,我们将要使用 patchValue,因为我们只更新 user
和 questioning
:
this.qService.editQue([params["id"]]).subscribe(res =>
this.question = res;
this.editqueForm.patchValue(
user: this.question.user,
questioning: this.question.questioning
);
);
编辑:如果你想做一些 ES6 的 Object Destructuring,你可能有兴趣这样做 ?
const user, questioning = this.question;
this.editqueForm.patchValue(
user,
questioning
);
哒哒!
【讨论】:
您能否详细分享一下setValue
和patchValue
的不同之处以及为什么它会在这种情况下起作用。
是的,我实际上已经包含了它。很抱歉在我最初的编辑中含糊不清。
嗨@wentjun,它不起作用。不过,我的表格只是空的。它没有显示数据。
哦,你应该在subscribe
中调用你的方法
我已经更新了我的答案。只是检查一下,this.question
包含一个值,对吗?尝试运行console.log(this.question)
。它不是未定义的吗?【参考方案2】:
在反应式表单中,有两种主要的解决方案来更新表单字段的值。
设置值:
在构造函数中初始化模型结构:
this.newForm = this.formBuilder.group(
firstName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(8)]],
lastName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(8)]]
);
如果要更新表单的所有字段:
this.newForm.setValue(
firstName: 'abc',
lastName: 'def'
);
如果要更新表单的特定字段:
this.newForm.controls.firstName.setValue('abc');
注意: 必须为 FormGroup 中的所有表单字段控件提供完整的模型结构。如果您错过任何属性或子集集合,则会引发异常。
补丁值:
如果您想更新表单的某些/特定字段:
this.newForm.patchValue(
firstName: 'abc'
);
注意: 不必为 FormGroup 中的所有/任何表单字段控件提供模型结构。如果您错过任何属性或子集集合,那么它不会抛出任何异常。
【讨论】:
第三点应该更正为,如果要更新表单的特定字段:this.newForm.controls.firstName.setValue('abc');【参考方案3】:试试这个。
editqueForm = this.fb.group(
user: [this.question.user],
questioning: [this.question.questioning, Validators.required],
questionType: [this.question.questionType, Validators.required],
options: new FormArray([])
)
setValue() 和 patchValue()
如果你想设置一个控件的值,这将不起作用,因此你必须设置两个控件的值:
formgroup.setValue(name: ‘abc’, age: ‘25’);
有必要提到方法内部的所有控件。如果不这样做,就会抛出错误。
另一方面,patchvalue()
在这方面要容易得多,假设您只想将名称分配为新值:
formgroup.patchValue(name:’abc’);
【讨论】:
TAB,这不行,定义editqueForm时,“this.question”没有值。 我已经在我的订阅者中做到了:ngAfterViewInit(): void this.childDetailDS$.subscribe((data) => this.gDetailDS = data; this.cityPlaceForm = this.formBuilder。 group( cpCode: [this.gDetailDS.cpCode, Validators.required], cpName: [this.gDetailDS.cpName, Validators.required], 省份: [this.gDetailDS.province], status: [this.gDetailDS.status] , 版本号: [this.gDetailDS.versionNo] ); ); 不使用 ngAfterViewInit -是的,您不知道在 ngAfterViewInit 中是否有价值-,您必须在“订阅”中创建表单,请参阅我的答案【参考方案4】:“通常”的解决方案是创建一个返回空 formGroup 或完整的 formGroup 的函数
createFormGroup(data:any)
return this.fb.group(
user: [data?data.user:null],
questioning: [data?data.questioning:null, Validators.required],
questionType: [data?data.questionType, Validators.required],
options: new FormArray([this.createArray(data?data.options:null])
)
//return an array of formGroup
createArray(data:any[]|null):FormGroup[]
return data.map(x=>this.fb.group(
....
)
然后,在 SUBSCRIBE 中调用函数
this.qService.editQue([params["id"]]).subscribe(res =>
this.editqueForm = this.createFormGroup(res);
);
小心!,您的表单必须包含 *ngIf 以避免初始错误
<form *ngIf="editqueForm" [formGroup]="editqueForm">
....
</form>
【讨论】:
【参考方案5】:要为单个表单控件/单独分配值,我建议通过以下方式使用 setValue:
this.editqueForm.get('user').setValue(this.question.user);
this.editqueForm.get('questioning').setValue(this.question.questioning);
【讨论】:
【参考方案6】:使用patchValue()
方法有助于更新控件的子集。
setValue()
this.editqueForm.patchValue(user: this.question.user, questioning: this.question.questioning)
来自 Angular 文档
setValue()
方法:
错误当严格检查失败时,例如设置不存在的控件的值,或者您排除了控件的值。
在您的情况下,对象缺少 options
和 questionType
控制值,因此 setValue()
将无法更新。
【讨论】:
以上是关于如何在 Angular 的反应式表单中设置表单控件的值的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular 7 响应式表单中设置 HTML Select Element 的选定值?
使用反应式表单在 Angular 中检查后,表达式发生了变化
如何在 Visual Studio 2017 中设置表单控件的工具提示属性