似乎在模板内部使用setter会导致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() {
}
}
Component.html
<h1>Test</h1>
<p>{{user.getId}}</p>
Component.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中使用复杂模型时,谁能推荐最佳实践以避免不必要的循环?甚至是调试这种行为的正确方法,就目前而言,我是console.logging getter方法并注意内存使用量的峰值。
编辑(答案) 经过更多时间的研究,深入研究堆栈跟踪,我发现无限变化检测循环实际上是由我们注入的称为“哨兵”的服务引起的。当使用console.log触发更改检测时,显然会导致问题。在此处找到了有关此问题的github问题:github.com/getsentry/sentry-javascript/issues/1883找不到解决方案(似乎天生就不兼容),如果找到解决方案,它将进行更新。
答案 0 :(得分:1)
使用ChangeDetectionStrategy.onPush
在通过 CLI 创建新组件时,运行以下命令使其成为项目的默认值。
ng config schematics.@schematics/angular.component.changeDetection OnPush
一般来说,尽量避免在模板中使用复杂的 getter 或调用函数。如果您需要转换数据,请考虑使用已记忆的 Pipes。