Angular输入框仅允许数字输入:如何显示错误提示?
Angular输入框非数字输入时显示错误提示方案
你的问题核心在于:现有指令会直接过滤掉非数字内容,导致表单控件的值始终是合法数字,因此Validators.pattern无法检测到错误。要解决这个问题,需要在指令中跟踪用户的原始输入,手动给表单控件设置错误状态,再在模板中根据错误状态展示提示。
步骤1:修改OnlyNumberDirective,添加错误状态控制
注入NgControl来访问表单控件实例,在用户输入非数字时设置错误,输入合法数字时清除错误:
import { Directive, ElementRef, forwardRef, HostListener, Renderer2 } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, NgControl } from '@angular/forms'; @Directive({ selector: '[onlyNumber]', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => OnlyNumberDirective), multi: true }] }) export class OnlyNumberDirective implements ControlValueAccessor { private onChange: (val: string) => void; private onTouched: () => void; private value: string; constructor( private elementRef: ElementRef, private renderer: Renderer2, private ngControl: NgControl // 新增:注入表单控件实例 ) { } @HostListener('input', ['$event.target.value']) onInputChange(value: string) { const filteredValue: string = filterValue(value); const hasInvalidInput = value !== filteredValue; // 根据输入合法性设置/清除错误 if (hasInvalidInput) { this.ngControl.control.setErrors({ invalidNumber: true }); } else { // 仅清除我们设置的错误,保留其他可能的验证错误 if (this.ngControl.control.errors?.invalidNumber) { delete this.ngControl.control.errors.invalidNumber; if (Object.keys(this.ngControl.control.errors).length === 0) { this.ngControl.control.setErrors(null); } } } this.updateTextInput(filteredValue, this.value !== filteredValue); } @HostListener('blur') onBlur() { this.onTouched(); } private updateTextInput(value: string, propagateChange: boolean) { this.renderer.setProperty(this.elementRef.nativeElement, 'value', value); if (propagateChange) { this.onChange(value); } this.value = value; } // ControlValueAccessor 接口实现 registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: any): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.renderer.setProperty(this.elementRef.nativeElement, 'disabled', isDisabled); } writeValue(value: any): void { value = value ? String(value) : ''; this.updateTextInput(value, false); } } function filterValue(value): string { return value.replace(/[^0-9]*/g, ''); }
步骤2:模板中添加错误提示
模板驱动表单
通过ngModel引用获取控件状态,当控件无效且已交互时显示提示:
<h3>Template Driven Form</h3> <form #form="ngForm"> <input name="number" type="text" onlyNumber [(ngModel)]="number" #numberInput="ngModel" class="form-control" /> <!-- 错误提示 --> <div *ngIf="numberInput.invalid && (numberInput.dirty || numberInput.touched)" style="color: red; margin-top: 4px;"> 请输入有效的数字 </div> <p>model value: {{ number }}</p> <p>form dirty: {{ form.dirty }}</p> </form>
响应式表单
通过表单组获取控件状态,同样在控件无效且已交互时显示提示:
<h3>Reactive Form</h3> <form [formGroup]="formGroup"> <input formControlName="number" type="text" onlyNumber class="form-control" /> <!-- 错误提示 --> <div *ngIf="formGroup.get('number').invalid && (formGroup.get('number').dirty || formGroup.get('number').touched)" style="color: red; margin-top: 4px;"> 请输入有效的数字 </div> <p>model value: {{ formGroup.get('number').value }}</p> <p>form dirty: {{ formGroup.dirty }}</p> </form>
原理说明
- 当用户输入非数字内容时,原始输入值和过滤后的值不一致,此时给控件设置
invalidNumber错误 - 当用户输入纯数字时,过滤前后值一致,清除
invalidNumber错误 - 模板通过检测控件的
invalid状态+dirty/touched状态,确保仅在用户交互后显示错误提示
内容的提问来源于stack exchange,提问作者Sard
相关产品推荐
相关产品推荐

