Добавить FormControl в соответствии с данными, возвращенными из бэкэнда, но получил две разные ошибки в приложении Angular - PullRequest
0 голосов
/ 14 февраля 2020

Это одна из страниц моего Angular приложения.

Внутри метода ngOnInit я дважды вызываю api для получения нужных мне разных данных и l oop через данные с помощью метода forEach чтобы построить реактивную форму, но каким-то образом я столкнулся с одной из двух разных ошибок.

Это

введите описание изображения здесь

и это

введите описание изображения здесь

и иногда вообще не возникает ошибок.

Буду признателен, если кто-нибудь скажет мне, что не так с моим кодом.

вот часть моего кода

user-manager.component.ts

export class UserManagerComponent implements OnInit {
    constructor(
    private fb: FormBuilder
  ) {}
    ngOnInit(): void {
        this.commonData.getDropdownData('menus')
        .pipe(takeWhile(() => this.alive))
        .subscribe(r => {
          if (r.status === 0) {
            this.menuForm = this.fb.group({});
            this.menuList = r.result.menus;
            this.menuList.forEach(i => {
              const control = new FormControl();
             (this.menuForm as FormGroup).setControl(i.MenuId, control);
              i.children.forEach(a => {
                const con = new FormControl();
                (this.menuForm as FormGroup).setControl(a.MenuId, con);
              });
            });
            this.isMenuFormReady = true;
      } else {
        this.toastrService.danger(r.message);
      }
    },
      error => {
        if (!environment.production) {
          this.menuForm = this.fb.group({});
          this.menuList = menuMock.menus;
          this.menuList.forEach(i => {

            const control = new FormControl();

            (this.menuForm as FormGroup).setControl(i.MenuId, control);

            i.children.forEach(a => {
              const con = new FormControl();
              (this.menuForm as FormGroup).setControl(a.MenuId, con);
            });

          });
          this.isMenuFormReady = true;
        }
          console.log(error);
      });

    this.commonData.getDropdownData('permissions')
    .pipe(takeWhile(() => this.alive))
    .subscribe(r => {
      if (r.status === 0) {
        this.permissionsForm = this.fb.group({});
        this.permissionsList = r.result;
        this.permissionsList = this.groupBy(this.permissionsList, function(item) {
          return [item.GroupId];
      });

      this.permissionsList.forEach(i => {

        const id = i[0].GroupId;
        this.permissionsForm.addControl(id, this.fb.group({}));

        i.forEach(a => {
          const con = new FormControl();
          (this.permissionsForm.get(id) as FormGroup).addControl(a.ActionId, con);
        });
      });
      this.isPermissionFormReady = true;

      } else {
        this.toastrService.danger(r.message);
      }
    },
      error => {
        if (!environment.production) {
          this.permissionsForm = this.fb.group({});
          this.permissionsList = userMock.Permission;
          this.permissionsList = this.groupBy(this.permissionsList, function(item) {
            return [item.GroupId];
        });

          this.permissionsList.forEach(i => {

            const id = i[0].GroupId;
            // console.log('id: ', id)
            this.permissionsForm.addControl(id, this.fb.group({}));

            i.forEach(a => {
              const con = new FormControl();
              (this.permissionsForm.get(id) as FormGroup).addControl(a.ActionId, con);
            });
          });
          this.isPermissionFormReady = true;
          // console.log(this.permissionsForm);
        }
          console.log(error);
      });
  }
    groupBy( array , f ) {
        const groups = {};
        array.forEach( function(o) {
            const group = JSON.stringify( f(o) );
            groups[group] = groups[group] || [];
            groups[group].push( o );
        });
        return Object.keys(groups).map( function( group ) {
            return groups[group];
        });
    }
}

user-manager.component. html

      <nb-card>

          <nb-card-header>
            form1
          </nb-card-header>
          <nb-card-body>
              <form [formGroup]="permissionsForm" autocomplete="off" *ngIf="isPermissionFormReady">
            <nb-card *ngFor="let item of permissionsList; let i = index;" [formGroupName]="i">
              <nb-card-header>
                {{item[0].GroupName}}
              </nb-card-header>
              <nb-card-body class="pt-0">
                <div class="row">
                  <div class="col-4 my-1" *ngFor="let permission of item">
                    <label>
                      <input type="checkbox" [formControlName]="permission.ActionId"/>
                      {{permission.ActionName}}
                    </label>
                  </div>
                </div>
              </nb-card-body>
            </nb-card>
          </form>
          </nb-card-body>

        </nb-card>

        <nb-card>
            <nb-card-header>
              form2
            </nb-card-header>
            <nb-card-body>
              <form [formGroup]="menuForm" autocomplete="off" *ngIf="isMenuFormReady">
                <div class="row">
                    <div class="col-4" *ngFor="let menu of menuList" >
                        <nb-card>
                          <nb-card-header>
                            <label>
                              <input type="checkbox" id="{{menu.MenuId}}" [formControlName]="menu.MenuId" (change)="menuClick($event)"/>
                              {{menu.title}}
                            </label>
                          </nb-card-header>
                          <nb-card-body class="pt-0">
                            <div class="row">
                              <div class="col-12 my-1" *ngFor="let item of menu.children">
                                <label>
                                  <input type="checkbox" id="{{item.MenuId}}" [formControlName]="item.MenuId" (change)="menuClick($event)"/>
                                  {{item.title}}
                                </label>
                              </div>
                            </div>
                          </nb-card-body>
                        </nb-card>
                      </div>
                </div>
              </form>
            </nb-card-body>
          </nb-card>

1 Ответ

1 голос
/ 14 февраля 2020

В настоящее время в Chrome 80 есть ошибка, из-за которой Array.reduce не работает в соответствии со спецификацией c. Поэтому, если вы используете реактивную форму в своем проекте, вы столкнетесь с проблемой браузера c, такой как (form.get ('key'). Значение не определено или значение не определено, даже если оно существует), которое нормально работало в chrome 79. Чтобы исправить эту проблему, добавьте Array.reduce polyfill в ваш angular проект вручную, как показано ниже.

Добавьте это к main.ts

(function () {
 function getChromeVersion() {
 const raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);

 return raw ? parseInt(raw[2], 10) : false;
    }

 const chromeVersion = getChromeVersion();
 if (chromeVersion && chromeVersion >= 80) {
      Array.prototype.reduce = function (callback /*, initialValue*/) {
 'use strict';
 if (this == null) {
 throw new TypeError('Array.prototype.reduce called on null or undefined');
        }
 if (typeof callback !== 'function') {
 throw new TypeError(callback + ' is not a function');
        }
 let t = Object(this), len = t.length >>> 0, k = 0, value;
 if (arguments.length === 2) {
          value = arguments[1];
        } else {
 while (k < len && !(k in t)) {
            k++;
          }
 if (k >= len) {
 throw new TypeError('Reduce of empty array with no initial value');
          }
          value = t[k++];
        }
 for (; k < len; k++) {
 if (k in t) {
            value = callback(value, t[k], k, t);
          }
        }
 return value;
      };
    }
  })();

ForMoreInfo

...