Angular 6如何在focusout时校验formControl值是否变更
解决方案
核心逻辑是维护一份已提交快照值做比对,从根源上避免无意义的emit触发,具体实现步骤如下:
- 在子组件内声明私有变量,存储最近一次成功向父组件emit的总英寸数作为比对基准,初始值和@Input传入的初始值对齐
- 监听@Input值的变更:如果父组件主动更新传入的总英寸值,除了将值换算为英尺+英寸填充表单外,必须同步更新比对基准值,避免父组件侧改值后校验逻辑失准
- 绑定focusOut事件时,先根据当前两个输入框的合法值计算出对应的总英寸数,空值、非数值统一做兜底处理(比如按0计算,可根据业务规则调整)
- 拿当前计算出的总英寸值和基准值做全等校验:数值完全一致时直接终止逻辑,不执行emit;数值存在差异时才向父组件传值,传值完成后立即更新基准值为当前的总英寸数
可直接复用的代码示例
import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core'; @Component({ selector: 'app-length-input', template: ` <input type="number" [(ngModel)]="foot" (focusout)="onInputBlur()" placeholder="英尺(Foot)"> <input type="number" [(ngModel)]="inch" (focusout)="onInputBlur()" placeholder="英寸(Inches)"> ` }) export class LengthInputComponent implements OnChanges { @Input() totalInches: number = 0; @Output() totalInchesChange = new EventEmitter<number>(); // 比对基准:记录上一次已提交的总英寸值 private lastSubmittedTotal: number = 0; foot: number = 0; inch: number = 0; ngOnChanges(changes: SimpleChanges): void { // 父组件传入值更新时,同步刷新表单和基准值 if (changes['totalInches']) { const latestVal = Number(changes['totalInches'].currentValue) || 0; this.foot = Math.floor(latestVal / 12); this.inch = latestVal % 12; this.lastSubmittedTotal = latestVal; } } onInputBlur(): void { // 计算当前表单对应的总英寸,做非法值兜底 const validFoot = Number(this.foot) || 0; const validInch = Number(this.inch) || 0; const currentTotal = validFoot * 12 + validInch; // 值无变更直接返回,不触发emit if (currentTotal === this.lastSubmittedTotal) return; // 值变更时才传值给父组件,同步更新基准 this.totalInchesChange.emit(currentTotal); this.lastSubmittedTotal = currentTotal; } }
补充说明:如果业务要求英寸值不能超过11(即满12自动进1英尺),可以在计算currentTotal之前先做进位格式化处理,不影响核心的比对校验逻辑。
内容的提问来源于stack exchange,提问作者karthik
相关产品推荐
相关产品推荐

