Angular 16响应式表单输入框:变更检测与样式重置问题
解决方案
一、修复输入框仅接受纯数字的问题
当前使用type="number"会允许输入e、+、-、.这类非纯数字字符,建议改为type="text"并通过以下方式限制输入:
- 替换输入框类型,配合键盘事件过滤非数字输入
- 优化表单验证正则,确保提交时仅校验纯数字
二、解决提交后修改输入不重置样式的问题
问题根源是提交后submitted状态始终为true,即使输入内容变化,样式仍会依据submitted && valid显示绿色栏。需要在输入变更时重置submitted状态,并优化样式判断逻辑。
修改后的完整代码
TypeScript代码
import { Component, OnInit } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-about', templateUrl: './about.component.html', styleUrls: ['./about.component.scss'] }) export class AboutComponent implements OnInit { public pageTitle = "Test input box"; submitted = false; custFormControl = new FormControl('', { validators: [ Validators.required, // 仅匹配6位或8位纯数字 Validators.pattern('^\\d{6}$|^\\d{8}$') ], updateOn: 'submit' }); inputFormGroup = new FormGroup({ inputCustNo: this.custFormControl }); ngOnInit(): void { // 监听输入变化,重置提交状态 this.custFormControl.valueChanges.subscribe(() => { this.submitted = false; }); } submit() { this.submitted = true; if (this.custFormControl.invalid) { console.log("Bummer"); return; } console.log("This went well", this.custFormControl.value); } // 过滤非数字输入 onKeyDown(event: KeyboardEvent): void { const allowedKeys = ['0','1','2','3','4','5','6','7','8','9','Backspace','Delete','ArrowLeft','ArrowRight','Tab']; if (!allowedKeys.includes(event.key)) { event.preventDefault(); } } }
HTML代码
<div class="card"> <div class="card-header"> <h2>{{pageTitle}}</h2> </div> <div class="card-body py-6"> <div class="container-fluid"> <form [formGroup]="inputFormGroup" (ngSubmit)="submit()"> <div class="form-group"> <label for="inputCustNo">Search for Data</label> <span class="form-info">Find Customer data</span> <div class="group" [ngClass]="{ 'is-invalid': submitted && custFormControl.errors, 'is-valid': submitted && custFormControl.valid }"> <input type="text" [formControl]="custFormControl" class="form-control" id="inputCustNo" placeholder="Enter Customer number" maxlength="8" (keydown)="onKeyDown($event)" /> <button type="submit" class="btn btn-primary"> Search </button> </div> <span class="form-info"> <div *ngIf="submitted && custFormControl.errors" class="invalid-feedback"> <div *ngIf="custFormControl.errors?.['required']">Customer number is required</div> <div *ngIf="custFormControl.errors?.['pattern']">Input must be either 6 or 8 digits long</div> </div> </span> </div> </form> </div> </div> </div>
关键修改说明
输入限制优化:
- 将
type="number"改为type="text",避免浏览器默认允许的非数字字符 - 添加
maxlength="8"替代原onKeyPress长度限制,更可靠 - 通过
onKeyDown事件过滤非数字输入,仅允许数字键和必要的功能键
- 将
样式重置修复:
- 在
ngOnInit中订阅valueChanges,输入内容变化时自动将submitted设为false,重置样式状态 - 简化
ngClass逻辑,仅在提交后根据校验结果显示有效/无效样式,未提交时保持中性状态
- 在
内容的提问来源于stack exchange,提问作者Moe-Doe
相关产品推荐
相关产品推荐

