我有一个垫子表,我从后端获取值并显示在其中。现在我正在尝试添加一个新的可键入字段“cmnts”,它应该是一个文本字段并进行验证。我这里的问题是验证适用于每一行以及我在第一行中输入的任何文本,它出现在所有行中。我的表单控件名称是否应该对每一行都是唯一的。在那种情况下我应该如何在 ts 文件中使用。你能建议一下吗?
我的html代码如下:
<table mat-table [dataSource]="dataSource" class="" matSort >
<tbody>
<th><td>...</td></th>
<ng-container matColumnDef="cmts">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Comments
</th>
<form [formGroup]="commentsForm" >
<td mat-cell *matCellDef="let element">
<span *ngIf="element?.id=='321'">
<mat-form-field>
<input matInput id="cmnts" formControlName="cmnts" required>
<mat-error *ngIf="submitted || h.cmnts.errors || h.cmnts.touched">
<span *ngIf="h.cmnts.errors?.required">cmnts is Required</span>
</mat-error>
<mat-error *ngIf="submitted || h.cmnts.errors">
<span *ngIf="h.cmnts.errors?.minlength"> Minimum length should be 10</span>
</mat-error>
<mat-error *ngIf="submitted || h.cmnts.errors">
<span *ngIf="h.cmnts.errors?.maxlength"> Maximum length should be 30 </span>
</mat-error>
</mat-form-field>
</span>
</td>
</form>
</ng-container>
我的Ts档案:
commentsForm: FormGroup;
this.commentsForm = this.fb.group({
cmnts: ['', [Validators.required,Validators.minLength(10), Validators.maxLength(40)]],
})
get h() { return this.commentsForm.controls; }
我也尝试过使用 formArray,如下所示。仍然无法为每一行单独设置验证。请建议。 //更新
<form [formGroup]="CmntsForm" >
<td mat-cell *matCellDef="let element;let rowIndex = index">
<span *ngIf="element?.sts=='A'">
<mat-form-field>
<input matInput id="cmnts" formControlName="cmnts" required>
</mat-form-field>
</span>
</td>
ts:
this.CmntsForm = this.fb.group({
cmnts: this.fb.array( ['', [Validators.required,Validators.minLength(1), Validators.maxLength(30)]])
})
get cmnts(){
return this.CmntsForm.controls["cmnts"] as FormArray;
}
您需要为每一行配置具有自己的验证规则的表单组的表单数组。这是最新版本的角度希望它有所帮助的示例。
HTML:
<form [formGroup]="commentsForm">
<table formArrayName="usercomments" mat-table [dataSource]="dataSource">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> ID </th>
<td mat-cell *matCellDef="let item"> {{item.id}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let item"> {{item.name}} </td>
</ng-container>
<ng-container matColumnDef="comment">
<th mat-header-cell *matHeaderCellDef> Comment </th>
<td mat-cell *matCellDef="let item; let rowIndex=index">
<div [formGroupName]="rowIndex">
<mat-form-field>
<input
placeholder="Enter comment"
formControlName="comment"
matInput
/>
<mat-error *ngIf="commentFormArray.controls[rowIndex].get('comment')?.hasError('required')">
Comment is required.
</mat-error>
</mat-form-field>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<button mat-raised-button [disabled]="commentsForm.invalid">Submit</button>
</form>
TS:
export interface UserComment {
id: number;
name: string;
comment: string;
}
export class UserCommentsComponent implements OnInit {
displayedColumns: string[] = ['id', 'name', 'comment'];
dataSource: UserComment[] = [
{ id: 1, name: 'John', comment: ''},
{ id: 2, name: 'Abram', comment: ''}
];
commentsForm: FormGroup;
constructor(private fb: FormBuilder){}
ngOnInit() {
this.commentsForm = this.fb.group({
usercomments: this.fb.array(this.loadUserComment(this.dataSource))
});
}
get commentFormArray() : FormArray {
return this.commentsForm.controls["usercomments"] as FormArray
}
private loadUserComment(comments: UserComment[]): FormGroup [] {
return comments.map((item: UserComment) =>
this.createCommentFormGroup(item));
}
private createCommentFormGroup(item: UserComment) : FormGroup{
return new FormGroup({
name: new FormControl(item.name),
comment: new FormControl(item.comment, [Validators.required])})
}
}
要解决此问题,您需要使每一行的表单控件名称唯一。一种方法是使用行索引作为表单控件名称的后缀。
以下是修改代码的方法:
在您的 HTML 中,将 formControlName="cmnts" 替换为
[formControlName]="'cmnts' + element.id":
<input matInput [formControlName]="'cmnts' + element.id" required>
这将通过将 element.id 附加到字符串“cmnts”来使表单控件名称对于每一行都是唯一的。
在您的 TS 文件中,您需要为每一行创建一个单独的表单控件。一种方法是创建一个表单控件数组并循环遍历数据源以初始化每个表单控件:
this.commentsForm = this.fb.group({});
this.dataSource.forEach((element) => {
this.commentsForm.addControl('cmnts' + element.id, new FormControl('', [Validators.required, Validators.minLength(10), Validators.maxLength(40)]));
});
此代码初始化一个空的表单组,然后循环遍历数据源为每一行创建一个表单控件。表单控件名称设置为 'cmnts' + element.id,这将匹配 HTML 中使用的表单控件名称。
最后,在您的 HTML 中,您需要将 h.cmnts 更新为 h['cmnts' + element.id] 以引用正确的表单控件:
<mat-error *ngIf="submitted || h['cmnts' + element.id].errors || h['cmnts' + element.id].touched">
<span *ngIf="h['cmnts' + element.id].errors?.required">Comments is required</span>
</mat-error>
<mat-error *ngIf="submitted || h['cmnts' + element.id].errors">
<span *ngIf="h['cmnts' + element.id].errors?.minlength">Minimum length should be 10</span>
</mat-error>
<mat-error *ngIf="submitted || h['cmnts' + element.id].errors">
<span *ngIf="h['cmnts' + element.id].errors?.maxlength">Maximum length should be 40</span>
</mat-error>
此代码使用表单控件名称'cmnts' + element.id 来引用表单组中正确的表单控件。