@HostListener 导致更改检测在我监听外部点击时触发太多次
@HostListener cause change detection triggers too many times when I'm listening for outside click
我有下一个根组件模板,它绘制了 9 个图块:
<ul>
<li *ngFor="let x of [0,1,2,3,4,5,6,7,8]">
<tile></tile>
</li>
</ul>
和下一个磁贴组件,我在其中添加了用于文档点击的 HostListener:
import {AfterViewChecked, Component, HostListener} from '@angular/core';
@Component({
selector: 'tile',
template: '<p>tile works!</p>'
})
export class TileComponent implements AfterViewChecked {
ngAfterViewChecked(): void {
console.log('checked');
}
@HostListener('document:click', ['$event'])
onOutsideClick(event: any): void {
// do nothing ...
}
}
笨蛋:http://plnkr.co/edit/7wvon25LhXkHQiMcwh48?p=preview
当我 运行 这样做时,我看到每次点击更改检测都被调用了 9^2 次:
我不明白为什么。
有人可以向我解释为什么在这种情况下更改检测会触发 n^2 次吗?
简答 - 这是设计使然。
因为我们有一个点击处理程序,angular 在调用处理程序后触发更改检测。
因此,当第一个组件处理点击时,它会导致更改检测。然后所有组件打印 "checked".
并且对每个组件都重复了一遍,所以我打印了 9^2 张 "checked."
另外请注意,OnPush 策略无助于减少打印量。
@Hostlistener 可能会很昂贵。在此处检查我的答案以最大程度地减少影响并提高性能。
我有下一个根组件模板,它绘制了 9 个图块:
<ul>
<li *ngFor="let x of [0,1,2,3,4,5,6,7,8]">
<tile></tile>
</li>
</ul>
和下一个磁贴组件,我在其中添加了用于文档点击的 HostListener:
import {AfterViewChecked, Component, HostListener} from '@angular/core';
@Component({
selector: 'tile',
template: '<p>tile works!</p>'
})
export class TileComponent implements AfterViewChecked {
ngAfterViewChecked(): void {
console.log('checked');
}
@HostListener('document:click', ['$event'])
onOutsideClick(event: any): void {
// do nothing ...
}
}
笨蛋:http://plnkr.co/edit/7wvon25LhXkHQiMcwh48?p=preview
当我 运行 这样做时,我看到每次点击更改检测都被调用了 9^2 次:
我不明白为什么。
有人可以向我解释为什么在这种情况下更改检测会触发 n^2 次吗?
简答 - 这是设计使然。
因为我们有一个点击处理程序,angular 在调用处理程序后触发更改检测。
因此,当第一个组件处理点击时,它会导致更改检测。然后所有组件打印 "checked".
并且对每个组件都重复了一遍,所以我打印了 9^2 张 "checked."
另外请注意,OnPush 策略无助于减少打印量。
@Hostlistener 可能会很昂贵。在此处检查我的答案以最大程度地减少影响并提高性能。