Patch the values in angular form

淺唱寂寞╮ 提交于 2019-12-02 01:28:09

in https://stackblitz.com/edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.component.html, I put as "path the values".

The only thing to take account is that you need add to the form as element as has the array.

  //This function serve to add to the array the elments of the arrays
  //Is the same that we use when add a new line to the Array Form
  addControls(control: string) {
    let question: any = this.questions.find(q => q.key == control);
    let children = question ? question.children : null;
    if (children)
      (this.form.get(control) as FormArray).push(this.qcs.toFormGroup(children))
  }
  this.dynamicFormService.getRest(url,token).subscribe(res => {
        //In res.data you have the data.
        //In res.dat.template_properties you has the array

        //Create the Form
        this.form = this.qcs.toFormGroup(this.questions);
        //Add so element at array as was necesary
        for (let i=0;i<this.data.myArray.length;i++)
        {
            this.addControls('template_properties')
        }
        //Finally use patchValue
        this.form.patchValue(res.data);
    }

Well, your data not corresponding with this.questions and there are a problem with your property_origin (about the problem with as convert propertyOrigin to a series of checkBox, let me some time -I'll updated this anwser more later-)

Updated see stackblitz updated Creating a new Question Type to create a list of checkBox There're a problem with the checkBox. In Angular a checkBox can be have only two values "true" or "false". Until I know, there no effect the attrib value.

So, we can not make something like

<input type="checkbox" value="car" formControlName="checkName">
<input type="checkbox" value="dog" formControlName="checkName">

To get in "checkName" an array ['car','dog'] if you checked the two values.

How we can solutionated this? I think that the better idea is has a formGroup like

<div formGroupName="checkName">
  <input type="checkBox" formControlName="car">
  <input type="checkBox" formControlName="dog">
</div>

So, we'll get some like

   checkName={car:true,dog:false}

Well one work is make a new QuestionType "ListCheckBoxQuestion"

export class ListCheckBoxQuestion extends QuestionBase<string> {
  controlType = 'list-chekbox';
  options: {key: string, value: string}[] = [];

  constructor(options: {} = {}) {
    super(options);
    this.options = options['options'] || [];
  }
}

After we can change the dinamic-formquestion.component adding a new switch. See that we create a formGroupName with the question.key, and inside this group we create a formControlName using "options"

<div [formGroupName]="question.key"  *ngSwitchCase="'list-chekbox'" >
  <ng-container *ngFor="let opt of question.options">
  <input type="checkbox"  [formControlName]="opt.key">
                <label >{{opt.value}}</label>
  </ng-container>
</div>

Well, the hard part is wen we create the form (the toFormGroup function of question-control-service

toFormGroup(questions: QuestionBase<any>[]) {
    let group: any = {};

    questions.forEach(question => {
      if (question.controlType=="array") {
         group[question.key]=new FormArray([]);
      }else if (question.controlType=="list-chekbox")
      { //We create a FromGroup using the options
        let controls:any={};
        for (let option of question.options)
             controls[option.key]=new FormControl(false);
        group[question.key]=new FormGroup(controls);
        console.log("*",question);
      }
      else {
       ...
      }
    });
    return new FormGroup(group);
  }

Well there're a job to to that is convert our form.value to data and the data received to form.value.

When we received some like ["car","dog"] we must transform to {car:true,dog:true} and when we have {car:true,dog:false} we must transform to ["car"]. We must use map

Update Take a look to the function toFormGroup of question-control-service. This function is the function that create the form. In the last version we add so many lines to the array as values length. Change this funcion to add a linea if no value is indicated

questions.forEach(question => {
      if (question.controlType == "array") {
        group[question.key] = new FormArray([]);
        if (question.value) {
          if (question.children) {
            //If question.children we must to give "value" to the children
            //So the children has as value, the value given in dataArray
            for (let value of question.value) {
              Object.keys(value).forEach(key => {
                let qu = question.children.find(x => x.key == key)
                if (qu) {
                  qu.value = value[key];
                  qu.controlType = qu.elementType
                }
              })
              group[question.key].push(this.toFormGroup(question.children))
            }
          }
        } //Add this lines to add one line to the array if no 
          //value is indicated
    else {
      if (question.children) {
        question.children.forEach(qu => {
          qu.controlType = qu.elementType

        })
        group[question.key].push(this.toFormGroup(question.children))
      }
    }

Use patchValue to set the data to form

this.dynamicFormService.getRest(url,token).subscribe(res => {
   this.form.patchValue({
      template_desc: res.data.template_desc,
      template_name:  res.data.template_name,
    });
 }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!