Заполните поля формы редактирования данными из API - Angular - PullRequest
1 голос
/ 01 ноября 2019

Кажется, я не могу найти подходящий пример того, как заполнить флажок значениями из API, когда форма находится в режиме редактирования.

У меня есть служба, которая извлекает данные о ролях из API. Каждая роль может иметь несколько разрешений, таких как edit-user, create-user, create-product, edit-product и т. Д. Мне нужна форма, в которой пользователь может редактировать эти разрешения роли с помощью флажков. Я попытался использовать 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>

...

Любая помощь будет принята с благодарностью?

Ответы [ 2 ]

1 голос
/ 02 ноября 2019

Я бы немного изменил настройки и повторил бы шаблон в шаблоне вместо permissionList. Также я бы вернул id:

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

, поскольку ваш permissionList использует id в качестве значения.

Вот так будет выглядеть форма перед редактированием. Здесь я опустил http-запрос и жестко закодировал значения:

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, и используйте patchValue() в элементе управления формы:

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

Вот демонстрационная версия STACKBLITZ .

0 голосов
/ 01 ноября 2019

Исправление или сброс массива форм довольно раздражает, вы можете проверить эту статью .

Вам необходимо обновить массив с необходимой длиной.

  • Вы можете добавить или удалить formControl в своем массиве, в зависимости от того, есть ли у вас более или менее элемент, когда вы хотите исправить патч.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...