d_s*_*ack 11 loops typescript angular angular6 angular-changedetection
似乎在模板中使用 getter 会导致 Angular 更改检测进入循环(getter 被调用数百次)。在阅读了大量关于类似问题的文章后,我似乎无法得到明确的答案。
背景资料:
从可维护性的角度来看,我确实相信在模板中使用 getter 是最干净的方法,但似乎是因为 Angular 在调用它之前无法知道 getter 值是否改变,它只是一直调用它。到目前为止,我发现了三个替代方案:
选项 1 似乎有悖于使用 Typescript 类的好处。选项 2 看起来像是不必要的代码重复并降低了可维护性,选项 3 将需要大量重构。
这是一个示例(出于说明目的而简化)
模型:
export class UserModel {
private id: string;
get getId() {
console.log('Getting id');
return this.id;
}
set setId(id) {
this.id = id;
}
constructor() {
}
}
Run Code Online (Sandbox Code Playgroud)
组件.html
<h1>Test</h1>
<p>{{user.getId}}</p>
Run Code Online (Sandbox Code Playgroud)
组件.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);
});
}
}
Run Code Online (Sandbox Code Playgroud)
会输出如下控制台日志: console.log output
任何人都可以推荐最佳实践来避免在 Angular 中处理复杂模型时出现不必要的循环吗?或者甚至是调试此类行为的正确方法,就目前而言,我正在控制台。记录 getter 方法并观察内存使用峰值。
编辑(答案) 经过更多时间调查、挖掘堆栈跟踪,我发现无限变化检测循环实际上是由我们注入的名为“Sentry”的服务引起的。显然,当使用 console.log 触发更改检测时会导致问题。在这里找到了一个关于它的 github 问题:github.com/getsentry/sentry-javascript/issues/1883没有找到解决方案(似乎本质上不兼容),如果我找到了解决方案,我会更新。