Angular中@for与ngFor的变更检测差异及@for渲染异常问题求助
Angular中@for与ngFor的变更检测差异及@for渲染异常问题求助
各位Angular开发者们好!我用ngFor很多年了,最近一直想切换到新的@for语法——毕竟在我看来它的代码风格更简洁。但最近我遇到了一个特别奇怪的现象,实在搞不清这是@for的某个我没理解的「特性」,还是真的碰到了bug,想在这里请教大家。
场景描述
我做了一个动态表单输入的功能:用户在输入框中输入内容时,会自动移除所有空内容的输入项,然后在底部添加一个新的空输入框。用ngFor实现的版本完全正常,但@for的版本在特定场景下会出现渲染异常,变更检测好像「懵了」。
代码实现
TypeScript 代码
// @for 相关逻辑 testingWithAtForNames: { name: string }[] = [{ name: '' }]; onTestingWithAtForChanged() { this.testingWithAtForNames = [ ...this.testingWithAtForNames.filter(x => x.name.length), // 移除空内容的项 { name: '' } // 底部添加新的空项 ]; } // ngFor 相关逻辑 testingWithNgForNames: { name: string }[] = [{ name: '' }]; onTestingWithNgForChanged() { this.testingWithNgForNames = [ ...this.testingWithNgForNames.filter(x => x.name.length), // 移除空内容的项 { name: '' } // 底部添加新的空项 ]; }
HTML 模板代码
<!-- @for 实现 --> <div style="margin: 10px; padding: 5px; border: 2px solid black; display: flex; flex-direction: column;"> <div>testing with @for</div> @for (testingWithAtForName of testingWithAtForNames; track $index) { <input [(ngModel)]="testingWithAtForName.name" (ngModelChange)="onTestingWithAtForChanged()"> } </div> <!-- ngFor 实现 --> <div style="margin: 10px; padding: 5px; border: 2px solid black; display: flex; flex-direction: column;"> <div>testing with NgFor</div> <input *ngFor="let testingWithNgForName of testingWithNgForNames" [(ngModel)]="testingWithNgForName.name" (ngModelChange)="onTestingWithNgForChanged()"> </div>
预期行为
- 初始状态:只有1个空输入框
- 用户在空输入框中输入内容后,底部自动出现新的空输入框
- 用户删除某个输入框的全部内容时,该空输入框会被移除,剩下的输入框自动上移,同时底部保持有一个空输入框
实际表现对比
ngFor 版本(完全正常)
- 初始:
[""] - 在第一个输入框输入"a"后:
["a", ""](正确渲染两个输入框) - 在第二个输入框输入"a"后:
["a", "a", ""](正确渲染三个输入框) - 删除第一个输入框的"a":
["a", ""](正确移除第一个空项,渲染两个输入框:"a"和空)
@for 版本(特定场景异常)
前三个步骤都正常,但第四步出现问题:
删除第一个输入框的"a"后,控制台打印的testingWithAtForNames数组是正确的["a", ""],但页面却渲染了两个空输入框!
更奇怪的是:
- 当所有输入框的内容相同时(比如都输入"a"或"asdf"),就会出现这个异常
- 当输入框的内容各不相同(比如第一个输入"qwer",第二个输入"asdf"),删除内容后渲染完全正常
我的疑问
我现在搞不清这是怎么回事:是我使用@for的方式不对吗?@for和ngFor在变更检测、追踪机制上到底有什么关键差异?这是Angular的bug,还是我没掌握@for的正确用法?
希望有经验的大佬能帮忙解惑,谢谢!
内容来源于stack exchange
相关产品推荐
相关产品推荐

