javascript - 以 Angular 形式修补值

标签 javascript angular typescript angular2-forms angular-reactive-forms

我正在使用 Angular 6 制作应用程序,我正在使用 Angular 动态形式。

在创建表单并提交时,我已经完成了所有工作,您可以看到正在运行的 stackblitzhttps://stackblitz.com/edit/angular-x4a5b6-hne6fg

仅供引用:此表单包含子元素,这些子元素将在单击添加按钮时打开并追加,并在单击删除按钮时逐个删除。

我需要的是,我只需要在编辑每一行时分别通过服务将值修补到每个输入..

假设我称获取服务为,

    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 中看到的形式,

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

如果我以 console.log(this.form.value) 形式控制表单,它给出的结果为,

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

console.log(res.data)中获取服务结果,

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 的数据绑定(bind)到所有表单输入中。

这些是我需要分别修补到所有输入的值,例如 template_name 具有 value 作为新模板和 template_desc 作为 新模板说明等。

对于 template_properties 值还有一个重要的事情,即数组将在创建期间单击添加按钮时打开,但在编辑期间它应该自动打开,并且 template_properties 中存在行数..

虽然这个问题为了解释而变大了一点,但我需要的是单一的..我需要将来自服务 (res.data) 的数据分别修补到每个表单元素和包括 template_properties 在内的所有表单元素都需要可见,用户可以在其中编辑和提交表单。

res.data的截图,enter image description here

尝试了以下答案,

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

但是如果我给 template_properties: res.data.template_properties,模板属性不会被绑定(bind)但是其他两个 template name 和 desc 被绑定(bind)..

请帮助实现数据到表单元素的修补...

最佳答案

https://stackblitz.com/edit/angular-x4a5b6-xcychx?file=src%2Fapp%2Fdynamic-form.component.html ,我将其作为“路径值”。

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

  //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 存在问题(关于将 propertyOrigin 转换为一系列复选框的问题,让我有时间 - 我稍后会更新这个答案 - )

已更新stackblitz updated 创建一个新的问题类型以创建一个复选框列表 复选框有问题。在 Angular 中,复选框只能有两个值“true”或“false”。直到我知道,属性值没有影响。

所以,我们不能做出类似的东西

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

如果检查了两个值,则在“checkName”中获取一个数组 ['car','dog']。

我们如何解决这个问题?我认为更好的想法是有一个类似 formGroup 的

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

所以,我们会得到一些像

   checkName={car:true,dog:false}

好吧,一个工作是创建一个新的问题类型“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

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

好吧,困难的部分是我们创建表单(question-control-service 的 toFormGroup 函数

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。

当我们收到类似 ["car","dog"] 的内容时,我们必须转换为 {car:true,dog:true} 并且当我们有 {car:true,dog:false} 时,我们必须转换为 ["car ”]。我们必须使用 map

更新 看一下问题控制服务的 toFormGroup 函数。该函数是创建表单的函数。在上一个版本中,我们将许多行添加到数组中作为值长度。如果没有指定值,则更改此函数以添加一条直线

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

关于javascript - 以 Angular 形式修补值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53220425/

相关文章:

javascript - Webpack 未正确编译(关键依赖项 : the request of a dependency is an expression)

javascript - MediaWiki 如何让 [Collapse] 链接不随文本移动位置?

javascript - angular2 一个元素上不能有多个模板绑定(bind)

angular - ng serve 在 Docker 容器中不起作用

javascript - Nodemon ts-node 无法监视 JavaScript 更改

javascript - cordova 插件网络接口(interface)问题

javascript - 根据for循环的索引查找小数指数

javascript - 以随机顺序动态地将div添加到另一个div中

Angular2 变化检测问题。如果类字段没有更改,但输入字段值不同,则输入字段不会更新

javascript - useRef : state becomes undefined after rendering