验证器可以完美地满足要求。但我需要唯一的验证器来检查标签是否有重复的名称。
当我在 inventory.component.ts 中切换到唯一时,该表甚至无法正确显示。
库存.组件.ts:
this.formBuilder.control(item['inventoryName'], RxwebValidators.unique())
// this.formBuilder.control(item['inventoryName'], Validators.required)
我注意到,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)
);
});
}
}
它无法处理 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(),
]),
})
);
});
}
}