如何验证mat-chip
已添加到mat-chip-list
。我正在使用ReactiveForms。我已经尝试过使用required
验证程序。
该值可以是名称列表,因此在提交表单之前,我需要确保名称列表中至少有1个名称。如果列表为空,则mat-error
将显示错误消息。使用required
验证程序会使表单无效,无论向列表中添加名称如何。
编辑:反应形式
我试图制作一个自定义验证器,现在我使用的是响应式表单,而不是模板驱动的表单,但是我无法使其正常工作。我编辑了以下代码以反映所做的更改,并创建了此https://stackblitz.com/edit/angular-4d5vfj
HTML
<form [formGroup]="myForm">
<mat-form-field class="example-chip-list">
<mat-chip-list #chipList formArrayName="names">
<mat-chip *ngFor="let name of myForm.get('names').controls; let i=index;"
[formGroupName]="i"
[selectable]="selectable"
[removable]="removable"
(removed)="remove(myForm, i)">
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input placeholder="Names"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event, asset)">
</mat-chip-list>
<mat-error>Atleast 1 name need to be added</mat-error>
</mat-form-field>
</form>
TS
import {COMMA, ENTER} from '@angular/cdk/keycodes';
import {Component} from '@angular/core';
import {FormGroup, FormControl, FormBuilder, FormArray} from '@angular/forms';
import {MatChipInputEvent} from '@angular/material';
@Component({
selector: 'chip-list-validation-example',
templateUrl: 'chip-list-validation-example.html',
styleUrls: ['chip-list-validation-example.css'],
})
export class ChipListValidationExample {
public myForm: FormGroup;
// name chips
visible = true;
selectable = true;
removable = true;
addOnBlur = true;
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
// data
data = {
names: ['name1', 'name2']
}
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
names: this.fb.array(this.data.names, this.validateArrayNotEmpty)
});
}
initName(name: string): FormControl {
return this.fb.control(name);
}
validateArrayNotEmpty(c: FormControl) {
if (c.value && c.value.length === 0) {
return {
validateArrayNotEmpty: { valid: false }
};
}
return null;
}
add(event: MatChipInputEvent, form: FormGroup): void {
const input = event.input;
const value = event.value;
// Add name
if ((value || '').trim()) {
const control = <FormArray>form.get('names');
control.push(this.initName(value.trim()));
console.log(control);
}
// Reset the input value
if (input) {
input.value = '';
}
}
remove(form, index) {
console.log(form);
form.get('names').removeAt(index);
}
}
答案 0 :(得分:4)
问题在于,当chipList
的{{1}}的状态为{{1}时,errorState
的{{1}}没有设置为true
}。
我正面临着同样的问题,不知道为什么这不能立即解决,或者如何通过chipList
的形式像FormArray
那样隐式地实现。
作为解决方法,您可以从INVALID
监听状态更改,并手动设置chipList
的{{1}}:
FormArray
答案 1 :(得分:1)
为了能够在mat-chip-list
上进行验证,我们必须将mat-input
和mat-chip-list
都与相同的FormControl
绑定,如下所示
正在工作的Stackblitz链接here
<form [formGroup]='group'>
<mat-form-field class="example-chip-list">
<mat-chip-list #chipList
required
formControlName="newFruit">
<mat-chip *ngFor="let fruit of fruits"
(removed)="remove(fruit)">
{{fruit.name}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input placeholder="New fruit..."
formControlName="newFruit"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)" required>
</mat-chip-list>
<!-- add mat-error -->
<mat-error *ngIf="group.controls.newFruit.hasError('required')">required!</mat-error>
</mat-form-field>
</form>
答案 2 :(得分:0)
不幸的是,无法使用Angular的任何预定义验证器,因为它们并非设计用于数组。我在这篇文章的帮助下设法做到了:
https://www.dev6.com/Angular_Material_Chips_with_Reactive_Forms_and_Custom_Validation
答案 3 :(得分:0)
this example由mmalerba所证明, 您可以使用两个单独的表单控件:一个用于mat-chip-list(这个应该是带有必需标志的一个),另一个用于输入。有趣的是,您必须在addEvent上手动设置两者的值:
<!-- ... -->
<mat-chip-list #chipList formControlName="names" required>
<!-- ... -->
<input placeholder="Names"
[formControlName]="name"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event, asset)">
</mat-chip-list>
<!-- ... -->
import {Validators} from '@angular/forms';
# ...
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
names: [this.data.names, Validators.required],
name: ['']
});
}
# ...
add(event: MatChipInputEvent, form: FormGroup): void {
const input = event.input;
const value = event.value;
// Add name
if ((value || '').trim()) {
const control = <FormArray>form.get('names');
control.push(this.initName(value.trim()));
console.log(control);
}
// Reset the input value
if (input) {
input.value = '';
}
// update form control (necessary for correct validation)
this.myForm.controls.name.setValue(null);
this.myForm.controls.names.setValue(this.data.names);
}
# ...
}
这是他们的stackblitz example