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

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

问题描述

我正在使用角度6进行应用程序,其中我正在使用角度动态形式.

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

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

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..

说我叫获取服务

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

我正在尝试将值修补为stacblitz中 dynamic-form.ts 中可以看到的格式,

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

如果我将表单的控制台设置为console.log(this.form.value),则结果为

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)

然后console.log(res.data)在获取服务结果中给出

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"

我只需要绑定来自 res.data 的数据,即可将其修补到所有表单输入.

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

这些分别是我需要修补到所有输入的值,例如template_name具有作为新模板,而template_desc具有New template description等.

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..

还有一个关于template_properties值的重要事项,即数组将在创建过程中单击添加"按钮时打开,而在编辑过程中,它应自动打开,并在template_properties中显示行数.

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..

尽管这个问题的解释用了一点,但我所需要的只是一个问题.我需要将来自服务(res.data)的数据分别修补到每个表单元素上,所有包括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.

res.data的屏幕截图,

The screenshot of res.data,

尝试以下答案,

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

但是,如果我给出template_properties: res.data.template_properties,则模板属性不会被绑定,而其他两个template name and desc会被绑定..

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...

推荐答案

.html"rel =" nofollow noreferrer> https://stackblitz.com/edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.component.html ,我将其作为路径值".

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

好吧,您的数据与this.questions不对应,并且您的property_origin存在问题(关于将convertOrigin转换为一系列checkBox的问题,让我花点时间-我稍后会更新此anwser-)

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

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

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">

如果您检查了两个值,则要在"checkName"中获取数组['car','dog'].

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

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

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}

另一项工作是制作一个新的QuestionType"ListCheckBoxQuestion"

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'] || [];
  }
}

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

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>

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

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

还有一个工作要做,那就是将我们的form.value转换为数据,并将接收到的数据转换为form.value.

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

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

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

更新 看一下问题控制服务的toFormGroup函数.此功能是创建表单的功能.在上一个版本中,我们在数组中添加了很多行作为值的长度.如果未指定任何值,请更改此功能以添加linea

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天全站免登陆