Angular Material:如何根据建议的选项验证自动完成?
Angular Material: How to validate Autocomplete against suggested options?
我们有一个带有 required
验证的自动完成输入。当用户通过输入查询来搜索选项时(但未选择任何选项),则输入有效,即使它不匹配任何建议的选项。
我想要实现的是不允许用户 post 表单,除非选择了建议的选项之一。我该如何实现?
<mat-form-field>
<input matInput placeholder="Pick one" aria-label="pick one" [matAutocomplete]="auto" [formControl]="form.controls['SELECTBOX_VALUE']">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of myOptions | async" [value]="option.name"> <span>{{ option.name }}</span> </mat-option>
</mat-autocomplete>
</mat-form-field>
<small *ngIf="!form.controls['SELECTBOX_VALUE'].valid && form.controls['SELECTBOX_DEGER'].touched" class="mat-text-warn">Please select.</small>
ngOnInit() {
this.form = this.fb.group({
... some other fields
SELECTBOX_VALUE: [null, Validators.required]
});
我的 Autocomplate 过滤器代码非常简单:
this.form.get('SELECTBOX_VALUE').valueChanges
.pipe(
startWith(''),
map(option => secenek ? this.doFilter(option) : this.options.slice())
);
doFilter (name: string) {
return this.myOptions.filter(option =>
option.name.toLowerCase().indexOf(name.toLowerCase()) === 0);
}
您可以在提交功能上添加字段验证检查,
Submit() {
if(this.form.valid) {
// send to API
} else {
// show error
}
}
对于那些可能需要类似方法的人。这是我的解决方案。我已经根据需要构建了自定义验证规则。
SELECTBOX_VALUE: [
null,
Validators.compose([
Validators.required,
FormCustomValidators.valueSelected(this.myArray),
]),
];
export class FormCustomValidators {
static valueSelected(myArray: any[]): ValidatorFn {
return (c: AbstractControl): { [key: string]: boolean } | null => {
let selectboxValue = c.value;
let pickedOrNot = myArray.filter(
(alias) => alias.name === selectboxValue
);
if (pickedOrNot.length > 0) {
// everything's fine. return no error. therefore it's null.
return null;
} else {
//there's no matching selectboxvalue selected. so return match error.
return { match: true };
}
};
}
}
有两种情况 Angular Material Autocomplete 可能需要根据所选选项列表进行验证:
- 字符串数组 - 建议的选项在字符串数组中定义
- 对象数组 - 建议的选项是在对象数组上定义的对象 属性(在这种情况下,将使用
displayWith
输入。 )
** Stackblitz Demo **
验证字符串数组中的选项
要根据字符串选项数组验证 autocomplete
,验证器可以接受选项数组并检查是否包含控制值。
function autocompleteStringValidator(validOptions: Array<string>): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
if (validOptions.indexOf(control.value) !== -1) {
return null /* valid option selected */
}
return { 'invalidAutocompleteString': { value: control.value } }
}
}
可以将验证器与其他内置验证器(例如 Validators.required
:
一起添加到 FormControl
public autocompleteControl = new FormControl('',
{ validators: [autocompleteStringValidator(this.options), Validators.required] })
从对象数组验证选项
为了根据对象选项数组验证 autocomplete
,验证器可以利用这样一个事实,即如果有效的 Object
选项,control.value
只会是 string
还没有被选中。
function autocompleteObjectValidator(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
if (typeof control.value === 'string') {
return { 'invalidAutocompleteObject': { value: control.value } }
}
return null /* valid option selected */
}
}
我们有一个带有 required
验证的自动完成输入。当用户通过输入查询来搜索选项时(但未选择任何选项),则输入有效,即使它不匹配任何建议的选项。
我想要实现的是不允许用户 post 表单,除非选择了建议的选项之一。我该如何实现?
<mat-form-field>
<input matInput placeholder="Pick one" aria-label="pick one" [matAutocomplete]="auto" [formControl]="form.controls['SELECTBOX_VALUE']">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of myOptions | async" [value]="option.name"> <span>{{ option.name }}</span> </mat-option>
</mat-autocomplete>
</mat-form-field>
<small *ngIf="!form.controls['SELECTBOX_VALUE'].valid && form.controls['SELECTBOX_DEGER'].touched" class="mat-text-warn">Please select.</small>
ngOnInit() {
this.form = this.fb.group({
... some other fields
SELECTBOX_VALUE: [null, Validators.required]
});
我的 Autocomplate 过滤器代码非常简单:
this.form.get('SELECTBOX_VALUE').valueChanges
.pipe(
startWith(''),
map(option => secenek ? this.doFilter(option) : this.options.slice())
);
doFilter (name: string) {
return this.myOptions.filter(option =>
option.name.toLowerCase().indexOf(name.toLowerCase()) === 0);
}
您可以在提交功能上添加字段验证检查,
Submit() {
if(this.form.valid) {
// send to API
} else {
// show error
}
}
对于那些可能需要类似方法的人。这是我的解决方案。我已经根据需要构建了自定义验证规则。
SELECTBOX_VALUE: [
null,
Validators.compose([
Validators.required,
FormCustomValidators.valueSelected(this.myArray),
]),
];
export class FormCustomValidators {
static valueSelected(myArray: any[]): ValidatorFn {
return (c: AbstractControl): { [key: string]: boolean } | null => {
let selectboxValue = c.value;
let pickedOrNot = myArray.filter(
(alias) => alias.name === selectboxValue
);
if (pickedOrNot.length > 0) {
// everything's fine. return no error. therefore it's null.
return null;
} else {
//there's no matching selectboxvalue selected. so return match error.
return { match: true };
}
};
}
}
有两种情况 Angular Material Autocomplete 可能需要根据所选选项列表进行验证:
- 字符串数组 - 建议的选项在字符串数组中定义
- 对象数组 - 建议的选项是在对象数组上定义的对象 属性(在这种情况下,将使用
displayWith
输入。 )
** Stackblitz Demo **
验证字符串数组中的选项
要根据字符串选项数组验证 autocomplete
,验证器可以接受选项数组并检查是否包含控制值。
function autocompleteStringValidator(validOptions: Array<string>): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
if (validOptions.indexOf(control.value) !== -1) {
return null /* valid option selected */
}
return { 'invalidAutocompleteString': { value: control.value } }
}
}
可以将验证器与其他内置验证器(例如 Validators.required
:
FormControl
public autocompleteControl = new FormControl('',
{ validators: [autocompleteStringValidator(this.options), Validators.required] })
从对象数组验证选项
为了根据对象选项数组验证 autocomplete
,验证器可以利用这样一个事实,即如果有效的 Object
选项,control.value
只会是 string
还没有被选中。
function autocompleteObjectValidator(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
if (typeof control.value === 'string') {
return { 'invalidAutocompleteObject': { value: control.value } }
}
return null /* valid option selected */
}
}