如何设置值形成控制在反应形式的角度

我是新来的。实际上,我正在尝试从一个服务订阅数据,而这个数据,我正在从(例如,它就像一个编辑表单)传递给我的表单控件。

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)]在我的表单字段设置的值,我的元素,它是工作良好,并显示一个警告,它将在角度7版本弃用。

<textarea formControlName="questioning" [(ngModule)]="question.questioning" cols="70" rows="4"></textarea>

因此,我通过执行下面的操作来设置表单控件的值,但是元素没有显示这些值。

setValue(){
this.editqueForm.setValue({user: this.question.user, questioning: this.question.questioning})
}

有人能告诉我如何设置反应形式的值吗?

293595 次浏览

Setting or Updating of Reactive Forms Form Control values can be done using both patchValue and setValue. However, it might be better to use patchValue in some instances.

patchValue does not require all controls to be specified within the parameters in order to update/set the value of your Form Controls. On the other hand, setValue requires all Form Control values to be filled in, and it will return an error if any of your controls are not specified within the parameter.

In this scenario, we will want to use patchValue, since we are only updating user and questioning:

this.qService.editQue([params["id"]]).subscribe(res => {
this.question = res;
this.editqueForm.patchValue({
user: this.question.user,
questioning: this.question.questioning
});
});

EDIT: If you feel like doing some of ES6's Object Destructuring, you may be interested to do this instead 🙃

const { user, questioning } = this.question;


this.editqueForm.patchValue({
user,
questioning
});

Ta-dah!

Try this.

editqueForm =  this.fb.group({
user: [this.question.user],
questioning: [this.question.questioning, Validators.required],
questionType: [this.question.questionType, Validators.required],
options: new FormArray([])
})

setValue() and patchValue()

if you want to set the value of one control, this will not work, therefor you have to set the value of both controls:

formgroup.setValue({name: ‘abc’, age: ‘25’});

It is necessary to mention all the controls inside the method. If this is not done, it will throw an error.

On the other hand patchvalue() is a lot easier on that part, let’s say you only want to assign the name as a new value:

formgroup.patchValue({name:’abc’});

The "usual" solution is make a function that return an empty formGroup or a fullfilled 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({
....
})
}

then, in SUBSCRIBE, you call the function

this.qService.editQue([params["id"]]).subscribe(res => {
this.editqueForm = this.createFormGroup(res);
});

be carefull!, your form must include an *ngIf to avoid initial error

<form *ngIf="editqueForm" [formGroup]="editqueForm">
....
</form>

In Reactive Form, there are 2 primary solutions to update value(s) of form field(s).

setValue:

  • Initialize Model Structure in Constructor:

    this.newForm = this.formBuilder.group({
    firstName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(8)]],
    lastName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(8)]]
    });
    
  • If you want to update all fields of form:

    this.newForm.setValue({
    firstName: 'abc',
    lastName: 'def'
    });
    
  • If you want to update specific field of form:

    this.newForm.controls.firstName.setValue('abc');
    

Note: It’s mandatory to provide complete model structure for all form field controls within the FormGroup. If you miss any property or subset collections, then it will throw an exception.

patchValue:

  • If you want to update some/ specific fields of form:

    this.newForm.patchValue({
    firstName: 'abc'
    });
    

Note: It’s not mandatory to provide model structure for all/ any form field controls within the FormGroup. If you miss any property or subset collections, then it will not throw any exception.

To assign value to a single Form control/individually, I propose to use setValue in the following way:

this.editqueForm.get('user').setValue(this.question.user);


this.editqueForm.get('questioning').setValue(this.question.questioning);