我希望深入了解变更检测器在我们的应用程序中如何运行的细节。最近我发现我们的应用程序远远超出了我们的需要,并提交了Angular issue。我已经能够修复我所知道的所有地方,但是现在我希望有一个简单的方法来确切地知道变化探测器何时运行,为什么它在运行,以及哪些组件是脏的什么时候运行获取此信息的最佳和最简单方法是什么?
更新:因此您可以在AppView.detectChanges
中设置一个断点,以便在更改检测器运行时断开,然后逐步执行该代码,您可以看到正在检查的内容。但是,我仍然不确定如何轻松确定触发更改检测器的内容或者标记要检查的组件的人员。
答案 0 :(得分:3)
另一种方法是创建自定义装饰器以添加ngDoCheck
钩子并将其记录到页面中的组件,这样做的缺点是您必须将此装饰器添加到页面中的每个组件:< / p>
(window as any).calls = {};
export function debug() {
return (constructor: any) => {
if (!constructor.prototype.ngDoCheck) {
constructor.prototype.ngDoCheck = () => {
console.log("ngDoCheck", constructor.name);
const calls = (window as any).calls;
calls[constructor.name] = calls[constructor.name] ? calls[constructor.name] + 1 : 1;
};
}
};
}
(window as any).resetCalls = () => (window as any).calls = {};
您可以在控制台中查看calls
,了解最常被调用的组件的统计信息。
请记住,ngDoCheck
调用并不意味着对该组件运行更改检测,它表明更改检测正在父组件上运行。
尚不确定如何一致地确定实际触发变更检测的内容。有些想法会覆盖ngZone
或ChangeDetector
来记录实际触发器。
答案 1 :(得分:3)
注意:这是打开的:“什么触发变化检测器?”
我花了一些时间研究主题,但是我得出的结论是,不修改角度源代码就很难做到这一点。但是,我可以分享一些解决此问题的技巧。
ApplicationRef.prototype.tick
)上的更改检测。ApplicationRef.prototype.tick
上创建一个断点。onIvokeTask
方法调用。task
变量。此变量存储有关触发更改检测的操作的信息。对于某些事件(setTimeout
),callback
属性将与我传递给setTimeout
的回调完全相同,但例如click事件,它也会回调,但由一些有角装饰器包装。但是,您可以通过eventName
和target
之类的其他属性来确定操作。是的,我知道这太复杂了,但是我不知道更好的解决方案。如果有人可以做得更好,请分享! :)
答案 2 :(得分:0)
尽管调试本身仍然是一个遥不可及的目标,但是practical demo和accompanying article至少可以更好地理解这一切的原理。
编辑:另请参见10 Things Every Angular Developer Should Know About Zone.js