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

Angular动态表单输入框输入单个字符后失焦问题求助

输入框输入单个字符后失焦问题解决方案

我已尝试StackOverflow上所有类似问题的解决方案,但仍无法解决输入框输入单个字符后失去焦点的问题。相关代码如下:

Component.ts 代码

private initForm() {
    if (this.form) {
        this.form.patchValue(this.course);

    } else {

        var controlsConfig = {
            duration: [this.course.duration],
            credits: [this.course.credits],
            expires: [],
            comment: [this.course.comment]
        };

        // 添加自定义字段到表单控件
        for (var i = 0; i < this.courseCustomFields.length; i++) {
            controlsConfig[this.courseCustomFields[i].key] = [this.course[this.courseCustomFields[i].key]];
        }

        this.form = this.formBuilder.group(controlsConfig);
    }
}

Component.html 代码

<div class="row" *ngFor="let courseCustomFieldRow of courseCustomFieldsForFront">
     <div class="col-md-3" *ngFor="let courseCustomField of courseCustomFieldRow">
         <div class="form-group">
              <label>{{courseCustomField.title}}</label>
              <input type="text" class="form-control" [formControlName]="courseCustomField.key">
         </div>
     </div>
</div>

问题排查与解决办法

1. 为*ngFor添加trackBy函数

Angular的*ngFor默认依赖对象引用追踪DOM元素,当表单值更新时,若courseCustomFieldsForFront或内部对象被重新创建,Angular会销毁并重建所有循环生成的DOM节点,直接导致输入框失焦。

解决步骤:

  • 在组件类中添加trackBy函数:
    trackByCustomField(index: number, field: any): string {
        return field.key; // 使用自定义字段的唯一key作为追踪标识
    }
    
  • 修改模板中的循环语句:
    <div class="row" *ngFor="let courseCustomFieldRow of courseCustomFieldsForFront; trackBy: trackByCustomField">
         <div class="col-md-3" *ngFor="let courseCustomField of courseCustomFieldRow; trackBy: trackByCustomField">
             <!-- 原有输入框代码不变 -->
         </div>
    </div>
    

2. 避免initForm重复触发

若initForm在输入过程中被意外调用(比如组件变更检测时重复执行),会导致表单被重新构建或执行patchValue,触发DOM重渲染。

解决步骤:

  • 检查initForm的调用时机,确保仅在组件初始化或course/courseCustomFields首次变更时执行,例如结合ngOnChanges:
    import { SimpleChanges, OnChanges, OnInit } from '@angular/core';
    
    // 组件类实现OnChanges接口
    ngOnChanges(changes: SimpleChanges) {
        if ((changes['course'] && !changes['course'].firstChange) || (changes['courseCustomFields'] && !changes['courseCustomFields'].firstChange)) {
            if (this.form) {
                this.form.patchValue(this.course);
            } else {
                this.initForm();
            }
        }
    }
    
    ngOnInit() {
        this.initForm();
    }
    

3. 替换var为let避免作用域问题

原循环中使用var i存在函数作用域污染风险,虽然不直接引发失焦,但建议替换为块级作用域的let,减少潜在问题:

for (let i = 0; i < this.courseCustomFields.length; i++) {
    controlsConfig[this.courseCustomFields[i].key] = [this.course[this.courseCustomFields[i].key]];
}

内容的提问来源于stack exchange,提问作者Dula

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:30:30