如何设置值以形成对反应形式的控制

时间:2019-03-21 06:40:31

标签: angular angular7 angular-reactive-forms

大家好,我是新手。实际上,我正在尝试从服务中订阅数据,然后将该数据传递给我的表单控件(例如,它就像一个编辑表单)。

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

谁能告诉我如何设置值来挖掘反应形式。请建议我。

6 个答案:

答案 0 :(得分:5)

设置或更新反应性表单可以使用patchValue和setValue来完成表单控制值。但是,在某些情况下,最好使用patchValue

patchValue不需要在参数中指定所有控件,即可更新/设置表单控件的值。另一方面,setValue需要填写所有“表单控件”值,如果未在参数中指定任何控件,它将返回错误。

在这种情况下,我们将要使用patchValue,因为我们仅更新userquestioning

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

Ta-dah!

答案 1 :(得分:2)

“常规”解决方案是使函数返回空的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>

答案 2 :(得分:1)

活动表单中,有2种主要解决方案来更新表单字段的值。

setValue:

  • 在构造函数中初始化模型结构

    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({
       firstName: 'abc'
    });
    

注意: 必须为FormGroup中的所有表单域控件提供完整的模型结构。如果您错过任何属性或子集集合,那么它将引发异常。

patchValue:

  • 如果要更新某些/特定形式的字段:

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

注意: 并非必须为FormGroup中的所有/任何表单字段控件提供模型结构。如果您错过任何属性或子集集合,那么它将不会引发任何异常。

答案 3 :(得分:0)

使用patchValue()方法有助于更新控件的子集。

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


通过Angular文档setValue()方法:

  

错误如果严格检查失败,例如设置不存在的控件的值或 排除控件的值

在您的情况下,对象缺少optionsquestionType的控制值,因此setValue()将无法更新。

答案 4 :(得分:0)

尝试一下。

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

答案 5 :(得分:0)

要将值/分别分配给单个Form控件,我建议通过以下方式使用 setValue

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

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