如何使用angular2 Reactive表单构建嵌套数组?

时间:2017-04-04 10:56:13

标签: json angular multidimensional-array angular2-template angular2-forms

I have an array like 
[  
   {  
      "PermissionRoleModule":{  
         "id":1,
         "legend":"businessModule",
         "group":[  
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"create Business"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            },
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"edit business"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            }
         ]
      }
   },
   {  
      "PermissionRoleModule":{  
         "id":2,
         "legend":"PanicModule",
         "group":[  
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"create panic"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            },
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"edit panic"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            }
         ]
      }
   }
]

我的观点如附件enter image description here

所示

当我点击提交按钮时,我期待json喜欢

[  
   {  
      "name":"aaa",
      "description":"das",
      "permission":[  
         {  
            "permission_id":1,
            "relation":2
         }
      ]
   }
]

如何使用反应形式为此案例构建表单组

我试过这个

component.ts

roleForm: FormGroup;
  formField: any;
validateForm() {
this.formField['rolename'] = new FormControl('', Validators.compose([Validators.required]))
this.formField['roledescription'] = new FormControl('', Validators.compose([Validators.required]))

this.form_objects.forEach(element => {
  if (element.group) {
    element.group.forEach(PermissionRoleGroup => {
      this.formField[PermissionRoleGroup.permission.key] = new FormControl({value:''}, Validators.compose([Validators.required]))

      if (PermissionRoleGroup.roles) {
        PermissionRoleGroup.roles.forEach(role => {
          this.formField[role.key] = new FormControl('', Validators.compose([Validators.required]))
        });
      }

    })
  }
});

this.roleForm = this.fb.group(this.formField);
 }

HTML

   <div  class="form-row" *ngFor="let element of form_objects; let i = index; ">

              <table  class="table table-bordered">
                <tr *ngFor="let permissionRoleGroup of element.group;let j= index;">
                  <table class="table table-bordered" style="margin-bottom: 0px;">
                    <td width="40%">
                      <label class="font-light">
                        <input type="checkbox"

                               [id]="permissionRoleGroup.permission.key"
                               [formControlName]="permissionRoleGroup.permission.key"
                               [value] = "permissionRoleGroup.permission.value">
                        {{permissionRoleGroup.permission.label }}-{{permissionRoleGroup.permission.ischecked}}
                      </label>
                    </td>

                    <td width="15%" *ngFor="let role of permissionRoleGroup.roles">
                      <label class="font-light">
                        <input   type="checkbox"

                                 [value] = "role.value"
                                 [formControlName]=" role.key">
                        {{role.label}}-{{role.ischecked}}
                      </label>
                    </td>
                  </table>
                </tr>
              </table>

            </div>

有了这个我能够构建表单,在提交过程中,我的表单不是创建json。

这是plunker链接https://plnkr.co/edit/h2VuBw4uITi6czn98ViS?p=preview

因为我是angular-2的初学者所以请帮助我。

2 个答案:

答案 0 :(得分:3)

我会创建一些属性,如permissionGroups并展平您的数据

permissionGroups: any[];
...
this.permissionGroups = this.form_objects
   .reduce((acc, permission) => [...acc, ...permission.group], []);

然后我会像这样构建formGroup

const permissions = this.permissionGroups.map(group => {
  return this.fb.group({
    [group.permission.key]: false,
    roles: this.fb.array(group.roles.map(role => this.fb.control(false)))
  });
});

this.roleForm = this.fb.group({
  roleName: ['', Validators.required],
  roleDescription: ['', Validators.required],
  permissions: this.fb.array(permissions)
});

并按如下方式准备html:

<form [formGroup]="roleForm" (submit)="submit(roleForm.value)">
    <div class="form-group">
        <label>Name</label>
        <input type="text" class="form-control" formControlName="roleName">
    </div>
    <div class="form-group">
        <label>Description</label>
        <textarea rows="4" class="form-control" formControlName="roleDescription"></textarea>
    </div>          

    <div formArrayName="permissions">
      <div class="form-row" *ngFor="let permission of roleForm.controls.permissions.controls; let i = index; ">
         <table [formArrayName]="i">
            <tr>
              <table>
                <tr>
                    <td>
                      <label class="font-light">
                        <input type="checkbox" [formControlName]="permissionGroups[i].permission.key">
                        {{ permissionGroups[i].permission.key }}
                      </label>
                    </td>
                    <td *ngFor="let role of permission.controls.roles.controls; let j = index;">
                      <label class="font-light" formArrayName="roles">
                        <input type="checkbox" [formControlName]="j">    
                        {{ permissionGroups[i].roles[j].name }}         
                      </label>
                    </td>
                </tr>
            </table>
        </tr>
      </table>
    </div>
  </div>
  <button type="submit">Submit</button>
</form>

当您提交表单时,您需要将表单值转换为您想要的结果,如下所示:

submit(value) {
  this.result = Object.assign({}, value, {
    permissions: value.permissions
      .reduce((acc, permission, idx) => {
        return permission[this.permissionGroups[idx].permission.key] ?
          [
            ...acc,
            {
              permission_id: this.permissionGroups[idx].permission.id,
              relation: permission.roles
                .reduce((rolesAcc, role, roleIdx) => {
                  return role ? [...rolesAcc, this.permissionGroups[idx].roles[roleIdx].id] : rolesAcc;
                }, [])
            }
          ] : acc
      }, [])
  });
}

你会看到输出如:

{
  "roleName": "",
  "roleDescription": "",
  "permissions": [
    {
      "permission_id": 2,
      "relation": [
        1
      ]
    },
    {
      "permission_id": 2,
      "relation": [
        1,
        2
      ]
    }
  ]
}

您可以使用 Plunker Example

中的代码

另见

答案 1 :(得分:0)

我创建了以下功能:

patchValue(form:any, object:any){

    var iterate = (mForm:any, mObject:any)=> {
        for (var key in mObject) {
            if (Array.isArray(mObject[key])) {
                if(mForm.value[key] == undefined || mForm.value[key] == null){
                    if(Array.isArray(mForm.value)){
                        mForm.push(new FormArray([]));
                    } else {
                        mForm.addControl(key, new FormArray([]));
                    }
                }
                iterate(mForm.controls[key], mObject[key]);
            }
            else if (typeof mObject[key] == 'string' || typeof mObject[key] == 'number' || typeof mObject[key] == 'boolean' || mObject[key] == null) {
                if(mForm.value[key] == undefined || mForm.value[key] == null){
                    if(Array.isArray(mForm.value)){
                        mForm.push(new FormControl(''));
                    } else {
                        mForm.addControl(key, new FormControl(''));
                    }
                }
            }
            else if (mObject[key] != null && typeof mObject[key] == 'object') {
                if(mForm.value[key] == undefined || mForm.value[key] == null){
                    if(Array.isArray(mForm.value)){
                        mForm.push(new FormGroup({}));
                    } else {
                        mForm.addControl(key, new FormGroup({}));
                    }
                }

                iterate(mForm.controls[key], mObject[key]);
            }
            else {
                console.log(key);
                console.log('undefined element');
            }
        }
    };

    iterate(form, object);

    form.patchValue(object);
}

只需传递一个空表单和您的对象。它将根据您传递的对象构建表单:

this.form = this.fb.array([]);
this.template = [  
   {  
      "PermissionRoleModule":{  
         "id":1,
         "legend":"businessModule",
         "group":[  
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"create Business"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            },
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"edit business"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            }
         ]
      }
   },
   {  
      "PermissionRoleModule":{  
         "id":2,
         "legend":"PanicModule",
         "group":[  
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"create panic"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            },
            {  
               "PermissionRoleGroup":{  
                  "id":1,
                  "permission":{  
                     "controleType":"ff",
                     "id":2,
                     "key":"edit panic"
                  },
                  "roles":[  
                     {  
                        "id":1,
                        "name":"self"
                     },
                     {  
                        "id":2,
                        "name":"other"
                     }
                  ]
               }
            }
         ]
      }
   }
]
this.patchValue(this.form, this.template);

如果你想自己构建它,你必须手动完成...我会推荐你​​这篇文章:https://blog.thoughtram.io/angular/2016/06/22/model-driven-forms-in-angular-2.html