似乎在模板中使用 getter 会导致 Angular 更改检测进入循环(getter 被调用数百次)。在阅读了大量关于类似问题的文章后,我似乎无法得到明确的答案。
背景资料:
从可维护性的角度来看,我确实相信在模板中使用 getter 是最干净的方法,但似乎因为 Angular 在调用它之前无法知道 getter 值是否发生了变化,它只是一直调用它。到目前为止,我找到了三种选择:
- 停止使用 getter,公开所有属性并直接访问它们
- 将每个 getter 的值存储到组件上的公共属性中并绑定它而不是模板中的 getter
- 将 Angular 的 changeDetection 模式从默认更改为 onPush
对于使用 Typescript 类的好处,选项 1 似乎违反直觉。选项 2 似乎是不必要的代码重复并降低了可维护性,选项 3 需要进行重大重构。
这是一个示例(为说明目的而简化)
模型:
export class UserModel {
private id: string;
get getId() {
console.log('Getting id');
return this.id;
}
set setId(id) {
this.id = id;
}
constructor() {
}
}
组件.html
<h1>Test</h1>
<p>{{user.getId}}</p>
组件.ts
import {Component, OnInit} from '@angular/core';
import {TestModel} from './test.model';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
public user: UserModel;
ngOnDestroy() {
if (this.userObserver) { this.userObserver.unsubscribe(); }
}
ngOnInit() {
this.userObserver = this.userObservable.subscribe(
(data: UserModel) => {
this.user = data;
},
(err: any) => {
console.error(err);
});
}
}
将输出以下控制台日志: console.log output
任何人都可以推荐最佳实践来避免在 Angular 中处理复杂模型时出现不必要的循环吗?甚至是调试此类行为的正确方法,就目前而言,我是控制台。记录 getter 方法并观察内存使用峰值。
编辑(答案) 经过更多时间调查,挖掘堆栈跟踪后,我发现无限变化检测循环实际上是由我们注入的名为“Sentry”的服务引起的。显然,当使用触发更改检测的 console.log 时,它会导致问题。在这里找到了一个关于它的 github 问题:github.com/getsentry/sentry-javascript/issues/1883没有找到解决方案(似乎天生不兼容),如果我找到解决方案,将更新。