Ionic 3 Angular 5:实现tel输入框仅允许数字输入的指令优化
嘿,我懂你这个困扰!之前用keyup事件确实会让非数字字符先闪一下再消失,体验特别别扭。咱们可以换个思路,直接在字符输入到框里之前就拦截掉,完全复刻你Ionic1里指令的顺滑效果~
解决方案:直接拦截非数字输入
在Angular(Ionic3/Angular5)中,我们可以通过监听keydown事件阻止非允许字符的输入,再结合NgControl同步更新表单模型,完美实现你想要的效果。
完整指令代码
import { Directive, ElementRef, HostListener, Inject, Optional } from '@angular/core'; import { NgControl } from '@angular/forms'; @Directive({ selector: '[onlyDigits]' }) export class OnlyDigitsDirective { // 定义允许的按键:数字、控制键(退格、删除、箭头、Tab) private allowedKeys: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab']; constructor( private elementRef: ElementRef, // 注入NgControl,用于同步表单模型和视图 @Optional() @Inject(NgControl) private ngControl: NgControl ) { } @HostListener('keydown', ['$event']) onKeyDown(event: KeyboardEvent) { // 允许的按键直接放行 if (this.allowedKeys.includes(event.key)) { return; } // 阻止非允许按键的默认行为,字符根本不会输入到输入框 event.preventDefault(); } @HostListener('input', ['$event.target.value']) onInput(value: string) { // 处理粘贴等绕过keydown的场景,过滤非数字字符 const transformedValue = value.replace(/[^0-9]/g, ''); if (transformedValue !== value && this.ngControl) { // 同步更新表单模型和视图,和Ionic1里的$setViewValue+$render逻辑一致 this.ngControl.control.setValue(transformedValue); } } }
关键细节说明
keydown拦截:我们只放行数字键和必要的控制键(比如退格、删除、箭头导航),其他按键直接阻止默认行为,从根源上避免非数字字符出现在输入框里。input兜底处理:针对粘贴操作或者其他可能绕过keydown的输入场景,我们再做一次过滤,确保最终输入框里只有数字,同时同步更新表单模型,避免视图和模型不一致。NgControl注入:通过@Optional()标记,确保指令即使没有绑定ngModel也能正常运行,适配更多场景。
使用方式
和你之前的用法完全一样,直接在type="tel"的输入框上添加指令即可:
<input type="tel" onlyDigits [(ngModel)]="phoneNumber" placeholder="请输入数字">
这样修改后,非数字字符根本不会出现在输入框里,和你Ionic1里的指令体验完全一致!
内容的提问来源于stack exchange,提问作者nishil bhave
相关产品推荐
相关产品推荐

