以角度形式修补值 [英] Patch the values in angular form

查看:61
本文介绍了以角度形式修补值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 angular 6 制作应用程序,其中我使用的是 angular 动态形式.

在创建表单并提交时,我已经完成了所有工作,您可以看到正在运行的 stackblitz

尝试了以下答案,

 this.form.patchValue({template_desc: res.data.template_desc,模板名称:res.data.template_name,});

但是如果我给 template_properties: res.data.template_properties,模板属性没有被绑定,但其他两个 template name 和 desc 被绑定..

请帮忙实现对表单元素的数据打补丁...

解决方案

in https://stackblitz.com/edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.component.html,我把路径值".

唯一需要考虑的是,您需要像数组一样将元素作为元素添加到表单中.

//该函数用于将数组元素添加到数组中//和我们在数组表单中添加新行时使用的一样addControls(控制:字符串){让问题: any = this.questions.find(q => q.key == control);让孩子=问题?question.children : null;如果(儿童)(this.form.get(control) as FormArray).push(this.qcs.toFormGroup(children))}this.dynamicFormService.getRest(url,token).subscribe(res => {//在 res.data 你有数据.//在 res.dat.template_properties 你有数组//创建表单this.form = this.qcs.toFormGroup(this.questions);//根据需要在数组中添加元素for (让 i=0;i<this.data.myArray.length;i++){this.addControls('template_properties')}//最后使用patchValuethis.form.patchValue(res.data);}

好吧,你的数据与this.questions不对应,你的property_origin有问题(关于将propertyOrigin转换为一系列checkBox的问题,让我有时间 - 我稍后会更新这个anwser -)

已更新参见 stackblitz 更新创建新的问题类型以创建复选框列表复选框有问题.在 Angular 中,复选框只能有两个值true"或false".在我知道之前,属性值没有影响.

所以,我们不能做类似的事情

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

如果检查了两个值,则要在checkName"中输入一个数组 ['car','dog'].

我们如何解决这个问题?我认为更好的主意是有一个 formGroup 像

<input type="checkBox" formControlName="car"><input type="checkBox" formControlName="dog">

所以,我们会得到一些喜欢

 checkName={car:true,dog:false}

一项工作是创建一个新的 QuestionType "ListCheckBoxQuestion"

导出类 ListCheckBoxQuestion 扩展 QuestionBase;{controlType = 'list-chekbox';选项:{键:字符串,值:字符串}[] = [];构造函数(选项:{} = {}){超级(选项);this.options = options['options'] ||[];}}

在我们可以更改 dinamic-formquestion.component 添加一个新开关之后.看到我们使用 question.key 创建了一个 formGroupName,在这个组中我们使用options"创建了一个 formControlName

<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-容器>

好吧,最难的部分是我们创建表单(问题控制服务的 toFormGroup 函数

toFormGroup(questions: QuestionBase[]) {让组:任何= {};问题.forEach(问题=> {如果(问题.控制类型==数组"){group[question.key]=new FormArray([]);}else if (question.controlType=="list-chekbox"){//我们使用选项创建一个FromGroup让控件:any={};for(让选项为 question.options)控件[option.key]=new FormControl(false);group[question.key]=new FormGroup(controls);console.log("*",question);}别的 {...}});返回新的 FormGroup(group);}

嗯,有一项工作是将我们的 form.value 转换为数据,并将接收到的数据转换为 form.value.

当我们收到类似 ["car","dog"] 我们必须转换为 {car:true,dog:true} 并且当我们有 {car:true,dog:false} 我们必须转换为 ["car"].我们必须使用地图

更新看一下 question-control-service 的 toFormGroup 函数.这个函数是创建表单的函数.在上一个版本中,我们向数组添加了许多行作为值的长度.如果没有指定值,请更改此函数以添加 linea

questions.forEach(question => {if (question.controlType == "array") {group[question.key] = new FormArray([]);如果(问题.价值){如果(问题.孩子){//如果 question.children 我们必须给孩子们价值"//所以孩子们有作为值,在dataArray中给出的值for (let value of question.value) {Object.keys(value).forEach(key => {让 qu = question.children.find(x => x.key == key)如果(曲){qu.value = value[key];qu.controlType = qu.elementType}})group[question.key].push(this.toFormGroup(question.children))}}}//添加这一行,如果没有,则在数组中添加一行//值表示别的 {如果(问题.孩子){question.children.forEach(qu => {qu.controlType = qu.elementType})group[question.key].push(this.toFormGroup(question.children))}}

I am making an application using angular 6, where i am using angular dynamic form.

As of creating the form and submitting i have completed everything, You could able to see the working stackblitz, https://stackblitz.com/edit/angular-x4a5b6-hne6fg

FYI: This form has children elemts which will gets opened and also gets append on click the add button and removes one by last on click the remove button..

The thing i am in the need is, i just need to patch the values to each inputs via service during edit of each row respectively..

Say i call the get service as,

    this.dynamicFormService.getRest(url,token).subscribe(res => {
        this.form.value = res.data;   //Tried this line but got error (Cannot assign to 'value' because it is a constant or a read-only property)
     })

I am trying to patch the values to the form which you can see in dynamic-form.ts in stacblitz,

  ngOnInit() {
    this.form = this.qcs.toFormGroup(this.questions);
}

If i console the the form as console.log(this.form.value), it gives the result as,

template_desc: ""
template_name: ""
template_properties: Array(0)
length: 0
__proto__: Array(0)

And console.log(res.data) in get service result gives,

data:
template_obj_id: "123"
template_desc: "New template description"
template_name: "New Template"
template_properties: Array(1)
0:
property_name: "Property name"
property_origin: ["VBM"]
property_required: true
property_type: "Property type"

I just need to bind this data that comes from res.data to get patched to all the form inputs.

These are the values i need to patch to all the inputs respectively like template_name has the value as New Template and template_desc as New template description etc..

And also an another important thing for template_properties value which is array will get open on click add button during create but whereas during edit it should get opened automatically with number of rows present inside template_properties..

Though the question went little bigger for explanation, the thing i am in the need is single.. I need to patch the data comes from service (res.data) to each form elements respectively and all the form elements including template_properties needs to be visible in which user can edit and submit the form.

The screenshot of res.data,

Tried with the below answer,

 this.form.patchValue({
      template_desc: res.data.template_desc,
      template_name:  res.data.template_name,
    });

But if i give template_properties: res.data.template_properties, the template properties not getting binded but other two template name and desc getting binded..

Kindly help to achieve the patching of data to the form elements...

解决方案

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

这篇关于以角度形式修补值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆