错误:找不到名称为“0”的控件

问题描述 投票:0回答:1

请找到这些代码并帮助我解决此问题。
我创建了一个 formArray,并且由于 label 和 formControlName 彼此不相似,我使用了映射,并根据 api 响应初始化了表单。并根据赠款数组更新表单值。
这里的 grants 即 userPermissions 是一个对象数组,因此每个对象代表机构的一组权限。

import {
  Component,
  Input,
  OnChanges,
  OnInit,
  SimpleChanges,
} from '@angular/core';
import { UserPermissionsService } from '../../../services/user-permissions.service';
import {
  AbstractControl,
  FormArray,
  FormBuilder,
  FormControl,
  FormGroup,
} from '@angular/forms';
import { Grant, UserPermissionsReponse } from '../../../modals/users.model';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'web-messenger-user-permissions',
  templateUrl: './user-permissions.component.html',
  styleUrls: ['./user-permissions.component.scss'],
})
export class UserPermissionsComponent implements OnChanges, OnInit {
  @Input() userId = '';
  public permissionsForm: FormGroup;
  public isEditMode = false;
  public userPermissions!: Grant[];
  public allActions = [
    'admin-api-user-management',
    'admin-broadcast',
    'admin-ctn-management',
    'admin-ctn-reporting',
    'admin-external-messaging',
    'admin-institution-provisioning',
    'admin-institution-updates',
    'admin-reporting',
    'admin-user-activation',
    'admin-user-audit',
    'admin-user-lockunlock',
    'admin-user-provisioning',
    'admin-user-update-pager',
    'admin-user-update-permissions',
    'admin-user-update-tags',
    'admin-user-updates',
    'communicate-out',
    'inst-admin',
    'user-update-schedule',
    'view-phi',
  ];
  public formControlLabelMapping!: { [key: string]: string };

  constructor(
    private userPermissionsSvc: UserPermissionsService,
    private fb: FormBuilder,
    private translate: TranslateService
  ) {
    this.permissionsForm = this.fb.group({
      grants: this.fb.array([]),
    });
  
  }

  ngOnInit(): void {
    this.initializeFormControlLabelMapping();
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['userId'].currentValue) {
      console.log('user Id', this.userId);
      this.getUserPermissions(this.userId);
    }
  }

  get grantsFormArray() {
    return this.permissionsForm.get('grants') as FormArray;
  }


  getControls(control: AbstractControl): { [key: string]: AbstractControl } {
    return (control as FormGroup).controls;
  }

  public toggleEditMode(): void {
    this.isEditMode = !this.isEditMode;
  }

  public getUserPermissions(userId: string): void {
    this.userPermissionsSvc
      .getUserPermissions(userId)
      .subscribe((data: UserPermissionsReponse) => {
        this.userPermissions = data.permission.grants;
        console.log('User permissions:', this.userPermissions);
        this.initializeForm(this.userPermissions);
        console.log(
          'Form Array after initialization:',
          this.grantsFormArray.value
        );
      });
  }

  initializeForm(userPermissions: Grant[]) {
    const grantsArray = this.permissionsForm.get('grants') as FormArray;
    grantsArray.clear(); // Clear existing form groups if any

    userPermissions.forEach((grant) => {
      const grantGroup = this.fb.group({});
      this.allActions.forEach((action) => {
        grantGroup.addControl(
          action,
          new FormControl(grant.actions.includes(action))
        );
      });
      grantsArray.push(grantGroup);
    });
    console.log('Form structure:', this.permissionsForm.value);
  }

  addNewPermissionsSet() {
    const newGrantGroup = this.fb.group({});

    this.allActions.forEach((action) => {
      newGrantGroup.addControl(action, new FormControl(false));
    });

    this.grantsFormArray.push(newGrantGroup);
  }

  initializeFormControlLabelMapping() {
    this.formControlLabelMapping = {
      'inst-admin': this.translate.instant('viewUserAndInstitutionInfo'),
      'admin-user-provisioning': this.translate.instant('provisionUsers'),
      'admin-user-activation': this.translate.instant('manageUserActivation'),
      'admin-user-lockunlock': this.translate.instant('lockUnlockUser'),
      'admin-user-updates': this.translate.instant('updateUserInformation'),
      'admin-user-update-permissions': this.translate.instant(
        'updateUserPermissions'
      ),
      'admin-user-update-pager': this.translate.instant('updateUsersPagerNo'),
      'admin-user-update-tags': this.translate.instant('updateUserTags'),
      'admin-user-audit': this.translate.instant('auditUsersMessages'),
      'admin-api-user-management': this.translate.instant('manageApiUsers'),
      'admin-institution-provisioning': this.translate.instant(
        'provisionInstitutions'
      ),
      'admin-institution-updates': this.translate.instant(
        'updateInstitutionInformation'
      ),
      'admin-broadcast': this.translate.instant('SendBroadcastMessages'),
      'admin-external-messaging': this.translate.instant(
        'sendExternalMessages'
      ),
      'admin-reporting': this.translate.instant('executeReports'),
      'admin-ctn-management': this.translate.instant('managePatients'),
      'admin-ctn-reporting': this.translate.instant('viewAndReportPatientData'),
      'user-update-schedule': this.translate.instant('updateUserSchedule'),
      'view-phi': this.translate.instant('viewPHI'),
      'communicate-out': this.translate.instant('communicateOut'),
      // ... add other mappings as necessary
    };
  }

  public updateUserPermissions(): void {
    console.log('permission form', this.grantsFormArray.controls);
  }
}

这是我所做的更改以适应 grantsFromArray 并获取带有标签映射的表单控件。

<form [formGroup]="permissionsForm">
        <div class="p-4 border dark:border-gray-700 rounded w-full shadow-sm">
          <!-- ... -->
          <h3 class="font-medium text-secondary dark:text-white text-lg mb-4 flex justify-between flex-wrap">
            {{'institutionGrants' | translate}}
            <button class="btn btn-primary dark:btn-accent btn-sm text-white" (click)="addNewPermissionsSet()">
              {{'addAdditionalInstitutionGrants' | translate}}
            </button>
          </h3>
          <h4 class="flex justify-between mb-3 text-base">
            <span>{{'institution(s)' | translate}}:</span>
            <span *ngFor="let institute of userPermissions">
              <a class="link text-primary dark:text-accent font-medium">Intelegencia Okta</a>
            </span>
          </h4>
          <div *ngFor="let grantControl of grantsFormArray.controls; let i = index">
            <ng-container [formGroupName]="i">
              <div *ngFor="let action of getControls(grantControl) | keyvalue">
                {{action.key}}
                <label class="cursor-pointer label mb-1 rounded px-3 border dark:border-gray-700">
                  <span>{{ formControlLabelMapping[action.key] }}</span>
      
                  <!-- Combined ngIf for 'Yes' -->
                  <!-- <span *ngIf="!isEditMode" [ngClass]="{'text-green-500': action.value, 'text-neutral': !action.value}">
                    <em class="ph-bold" [ngClass]="{'ph-check-circle': action.value, 'ph-x': !action.value}"></em>
                    {{ action.value ? 'Yes' : 'No' }}
                  </span> -->
                  <span *ngIf="!isEditMode" [ngClass]="{'text-green-500': action.value.value, 'text-neutral': !action.value.value}">
                    <em class="ph-bold" [ngClass]="{'ph-check-circle': action.value.value, 'ph-x': !action.value.value}"></em>
                    {{ action.value.value ? 'Yes' : 'No' }}
                  </span>
                  
      
                  <!-- Checkbox in edit mode -->
                  <input *ngIf="isEditMode" type="checkbox" class="toggle toggle-primary toggle-sm" [formControlName]="action.key"/>
                </label>
              </div>
            </ng-container>
          </div>
          <!-- ... -->
        </div>
      </form>
javascript angular typescript angular-reactive-forms
1个回答
0
投票

您需要为您的formarray指定formArrayName

<ng-container formArrayName="grants">
  <div *ngFor="let grantControl of grantsFormArray.controls; let i = index">
    ...
  </div>
</ng-container>
© www.soinside.com 2019 - 2024. All rights reserved.