Mat 表中的 Angular FormArray 输入反应形式:所需的验证器工作完美,但 @rxweb/reactive-form-validators 不知何故不行

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

验证器可以完美地满足要求。但我需要唯一的验证器来检查标签是否有重复的名称。

当我在 inventory.component.ts 中切换到唯一时,该表甚至无法正确显示。
库存.组件.ts:

this.formBuilder.control(item['inventoryName'], RxwebValidators.unique())
// this.formBuilder.control(item['inventoryName'], Validators.required)

https://stackblitz.com/edit/stackblitz-starters-bj8b6n?file=src%2Fapp%2Finventory%2Finventory.component.ts

我注意到,stackoverflow 和文档上的所有其他示例都使用 RxwebValidators.unique() 和一个额外的键。

    addSkill(){
        let skillsArray = <FormArray>this.employeeFormGroup.controls.skills;
        skillsArray.push(this.getSkillFormGroup());
      }
  
      getSkillFormGroup(){
        // extra skillName key
        return this.formBuilder.group({
          skillName:['',RxwebValidators.unique()]
        })
      }

这是某种要求吗? https://docs.rxweb.io/form-validations/unique/validators

完整代码:
库存.html:

<p>Inventory Form Value: {{ inventoryForm.value | json }}</p>
<p>Form Status: {{ inventoryForm.status }}</p>

<div *ngIf="!inventoryForm.valid">
  <mat-card style="text-align: center; background-color:#ea8288">
    <mat-card-content>Inventory invalid</mat-card-content>
  </mat-card>
</div>
<form [formGroup]="inventoryForm">
  <div class="table-container">
    <table
      mat-table
      class="mat-elevation-z8"
      [dataSource]="inventorySource"
      formArrayName="inventoryFormArr"
    >
      <!-- ref.: https://stackoverflow.com/questions/51150193/angular-material-editable-table-using-formarray -->
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr
        mat-row
        *matRowDef="let row; let i = index; columns: displayedColumns"
      ></tr>
      <!--- Note that these columns can be defined in any order.
                The actual rendered columns are set as a property on the row definition" -->

      <!-- Name Column -->
      <ng-container matColumnDef="inventoryName">
        <th mat-header-cell *matHeaderCellDef>Name</th>
        <td
          mat-cell
          *matCellDef="
            let inventoryFormArr of inventoryFormArr.controls;
            let i = index
          "
        >
          <mat-form-field appearance="outline" style="margin-bottom: -1.25em">
            <input
              matInput
              autocorrect="off"
              autocapitalize="off"
              spellcheck="off"
              type="text"
              required
              type="text"
              [formControlName]="i"
            />
          </mat-form-field>
        </td>
      </ng-container>

      <!-- Quantity Column -->
      <ng-container matColumnDef="quantity">
        <th mat-header-cell *matHeaderCellDef>Quantity</th>
        <td mat-cell *matCellDef="let element">{{ element.quantity }}</td>
      </ng-container>
    </table>
  </div>
</form>

库存.组件.ts:

import { Component } from '@angular/core';
import { FormArray, FormBuilder } from '@angular/forms';
import { Validators } from '@angular/forms';
import { RxwebValidators } from '@rxweb/reactive-form-validators';

export interface myDataArray {
  inventoryName: string;
  quantity: number;
}

const ELEMENT_DATA: myDataArray[] = [
  { inventoryName: 'Cars', quantity: 14 },
  { inventoryName: 'Books', quantity: 49 },
];

@Component({
  selector: 'inventory-table',
  templateUrl: './inventory.component.html',
  styleUrls: ['./inventory.component.scss'],
})
export class InventoryComponent {
  displayedColumns: string[] = ['inventoryName', 'quantity'];

  inventorySource = ELEMENT_DATA;

  inventoryForm = this.formBuilder.group({
    inventoryFormArr: this.formBuilder.array([]),
  });

  constructor(private formBuilder: FormBuilder) {}

  get inventoryFormArr() {
    return this.inventoryForm.get('inventoryFormArr') as FormArray;
  }

  ngOnInit(): void {
    this.inventorySource.forEach((item) => {
      this.inventoryFormArr.push(
        //this.formBuilder.control(item['inventoryName'], RxwebValidators.unique())
        this.formBuilder.control(item['inventoryName'], Validators.required)
      );
    });
  }
}
angular typescript angular-material angular-reactive-forms angular-validation
1个回答
0
投票

它无法处理 formControls 数组,看起来像是验证器中的错误,不确定。

同时,作为一种解决方法,您可以创建一个 formGroups 的 formArray,并且验证似乎工作正常!

html

<p>Inventory Form Value: {{ inventoryForm.value | json }}</p>
<p>Form Status: {{ inventoryForm.status }}</p>

<div *ngIf="!inventoryForm.valid">
  <mat-card style="text-align: center; background-color:#ea8288">
    <mat-card-content>Inventory invalid</mat-card-content>
  </mat-card>
</div>
<form [formGroup]="inventoryForm">
  <div class="table-container">
    <table
      mat-table
      class="mat-elevation-z8"
      [dataSource]="inventorySource"
      formArrayName="inventoryFormArr"
    >
      <!-- ref.: https://stackoverflow.com/questions/51150193/angular-material-editable-table-using-formarray -->
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr
        mat-row
        *matRowDef="let row; let i = index; columns: displayedColumns"
      ></tr>
      <!--- Note that these columns can be defined in any order.
                The actual rendered columns are set as a property on the row definition" -->

      <!-- Name Column -->
      <ng-container matColumnDef="inventoryName">
        <th mat-header-cell *matHeaderCellDef>Name</th>
        <td
          mat-cell
          *matCellDef="
            let inventoryFormArr of inventoryFormArr.controls;
            let i = index
          "
          [formGroupName]="i"
        >
          <mat-form-field appearance="outline" style="margin-bottom: -1.25em">
            <input
              matInput
              autocorrect="off"
              autocapitalize="off"
              spellcheck="off"
              type="text"
              required
              type="text"
              formControlName="inventoryName"
            />
          </mat-form-field>
        </td>
      </ng-container>

      <!-- Quantity Column -->
      <ng-container matColumnDef="quantity">
        <th mat-header-cell *matHeaderCellDef>Quantity</th>
        <td mat-cell *matCellDef="let element">{{ element.quantity }}</td>
      </ng-container>
    </table>
  </div>
</form>

ts

import { Component } from '@angular/core';
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
import { Validators } from '@angular/forms';
import { RxwebValidators } from '@rxweb/reactive-form-validators';

export interface myDataArray {
  inventoryName: string;
  quantity: number;
}

const ELEMENT_DATA: myDataArray[] = [
  { inventoryName: 'Cars', quantity: 14 },
  { inventoryName: 'Books', quantity: 49 },
];

@Component({
  selector: 'inventory-table',
  templateUrl: './inventory.component.html',
  styleUrls: ['./inventory.component.scss'],
})
export class InventoryComponent {
  displayedColumns: string[] = ['inventoryName', 'quantity'];

  inventorySource = ELEMENT_DATA;

  inventoryForm = this.formBuilder.group({
    inventoryFormArr: this.formBuilder.array([]),
  });

  constructor(private formBuilder: FormBuilder) {}

  get inventoryFormArr() {
    return this.inventoryForm.get('inventoryFormArr') as FormArray;
  }

  ngOnInit(): void {
    this.inventorySource.forEach((item) => {
      this.inventoryFormArr.push(
        //this.formBuilder.control(item['inventoryName'], RxwebValidators.unique())
        new FormGroup({
          inventoryName: this.formBuilder.control(item['inventoryName'], [
            Validators.required,
            RxwebValidators.unique(),
          ]),
        })
      );
    });
  }
}

堆栈闪电战

© www.soinside.com 2019 - 2024. All rights reserved.