【问题标题】:Fill Edit form Checkboxes with data from API - Angular使用来自 API 的数据填充编辑表单复选框 - Angular
【发布时间】:2020-02-27 13:32:09
【问题描述】:

当表单处于编辑模式时,我似乎找不到合适的示例来说明如何使用 API 中的值填充复选框。

我有一个从 API 获取角色数据的服务。每个角色都可以有多个权限,如编辑用户、创建用户、创建产品、编辑产品等。我想要一个用户可以使用复选框编辑这些角色权限的表单。我尝试使用如下所示的 patchValue,但到目前为止它没有任何响应。

  rolePermissionList = [];
  permissionList = [];

  setupForm() {

    this.roleForm = this.fb.group({
      role_name: ["", Validators.required],
      description: [""],
      status: [""],
      permissions: this.fb.array([]),
    }, {updateOn: 'change'});

  }


  ngOnInit() {

    this.setupForm();

    this.route.paramMap.subscribe(params => {

      this.id = parseInt(params.get("id"));

      // fetch single role record
      this.getPageData(this.id);

    })

  }

  // get page data
  async getPageData(role_id) {

    this.spinner.show();

    // get role
    await this.getRole(role_id);

    // get all permissions
    await this.getPermissions();

    // get role permissions
    await this.getRolePermissions(role_id);

    this.spinner.hide();

  }

我有两个服务:一个返回整个权限列表,另一个返回分配给当前角色的权限。我想要一种方法来仅检查分配给正在编辑的当前角色的权限。这些是获取所有权限和角色权限的函数:

// get permissions list

getPermissions() {

    this.permissionService.getPermissionsList()

      .subscribe(

        data => {

          console.log("permissions === ", data);

          this.permissionList = data;

        },

        error => console.log(error));

  }



  // get role permissions
  getRolePermissions(role_id?:any) {

    // if role_id is supplied
    let params = new HttpParams();
    if (role_id) {
      params=params.set('role_id', role_id.toString());
    }

    this.rolePermissionService.getRolePermissionsList(params)
      .subscribe(
        data => {

          // store fetched data
          this.rolePermissionList = data;

          // extract permission name from returned array
          var arrayOfPerms = data.map(function(obj) {
            return obj.name;
          });

          // patch data
          this.roleForm.pastchValue('permissions', arrayOfPerms);

        },
        error => {

          console.log(error);

        });

  }

前端:

...

<div class="row" *ngIf="permissionList; else loading">

   <div *ngFor="let permission of permissionList; let i=index" class="col-md-6">

      <div class="custom-control custom-checkbox mr-sm-2 m-b-15">
         <input type="checkbox"
          [value]="permission.id"
          (change)="onCheckChange($event)"
          class="custom-control-input"
          id="checkbox-{{ i }}">

       <label class="custom-control-label" for="checkbox-{{ i }}">{{  permission.display_name }}</label>
      </div>

   </div>

</div>

...

任何帮助将不胜感激?

【问题讨论】:

  • 您介意创建一个示例 StackBlitz 来使用吗?您可以通过HttpClientassets 文件夹中的json 文件中获取数据。只需在对HttpClientget 方法的调用中提供/assets/data.json 的url。请分享示例 stackblitz 的链接。或者你可以分叉我刚刚为这个answer创建的这个stackblitz

标签: angular forms typescript api checkbox


【解决方案1】:

我会稍微改变一下设置,并在模板中迭代一个表单数组而不是permissionList。我也会返回 id:

var arrayOfPerms = data.map(function(obj) {
  return obj.id;
});

因为您的permissionList 使用id 作为值。

这就是表单在编辑之前的样子。这里我省略了 http-request 并对值进行了硬编码:

permissionList = [
  { id: 1, displayName: 'Admin' },
  { id: 2, displayName: 'User' },
  { id: 3, displayName: 'SuperUser' }
];

rolePermissionList = [1, 3];

constructor(private fb: FormBuilder) {

  // set all checkboxes as false initially
  const ctrls = this.permissionList.map(control => this.fb.control(false));

  this.roleForm = this.fb.group({
    permissions: this.fb.array(ctrls),
  });
}

// for being able to shorten
get permissionsArr() {
  return this.roleForm.get('permissions') as FormArray;
}

submit() {
  // filter the checked and store in array
  const selectedRoles= this.roleForm.value.permissions
    .map((checked, i) => checked ? this.permissionList[i].id : null)
    .filter(value => value !== null);
  // here is an array of ids, e.g [1, 3]
  console.log(selectedRoles)
}

以及相关的模板部分:

<label formArrayName="permissions" *ngFor="let perm of permissionsArr.controls; index as i">
  <input type="checkbox" [formControlName]="i">
  {{permissionList[i].displayName}}
</label>

因此,完成此操作后,如果您想要修补值,只需调用一个函数来检查 permissionList 中匹配的 id,然后在表单控件上使用 patchValue()

patchValue() {
  this.permissionList.map((perm, i) => {
    if (this.rolePermissionList.indexOf(perm.id) !== -1) {
      this.permissionsArr.at(i).patchValue(true)
    }
  })
}

这是一个STACKBLITZ 演示。

【讨论】:

  • 感谢这对我有一些小的改动。干杯。
  • 太好了,太棒了,很高兴我能在路上帮助你! :)
【解决方案2】:

修补或重置表单数组非常烦人,您可以查看此article

你需要用必要的长度更新你的数组。

  • 您可以在数组中添加或删除 formControl,具体取决于您想要修补 vaue 时是否有更多或更少的项目。

【讨论】:

  • 是否可以以角度修补一组复选框?我知道这个问题一定有一个简单的答案,我就是想不通……
  • 是的,你可以。但是你的数组需要有正确的长度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 2014-07-08
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
  • 2022-10-20
  • 1970-01-01
相关资源
最近更新 更多