You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

关键修改说明

  1. 输入限制优化:

    • 将type="number"改为type="text",避免浏览器默认允许的非数字字符
    • 添加maxlength="8"替代原onKeyPress长度限制,更可靠
    • 通过onKeyDown事件过滤非数字输入,仅允许数字键和必要的功能键
  2. 样式重置修复:

    • 在ngOnInit中订阅valueChanges,输入内容变化时自动将submitted设为false,重置样式状态
    • 简化ngClass逻辑,仅在提交后根据校验结果显示有效/无效样式,未提交时保持中性状态

内容的提问来源于stack exchange,提问作者Moe-Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:55:04