我正在绑定一个滚动事件来捕获滚动并用它做一些事情,我已经创建了一个像bellow一样的指令:
所以我有简单的指令,除了:
constructor ( private el : ElementRef,private renderer : Renderer ) { this.domAdapter = new browser.BrowserDomAdapter(); this.ruler = new Ruler( this.domAdapter ); } ngAfterViewInit () : any { this.renderer.listenGlobal( 'window','scroll',()=> { console.log( 'scrolling' ); } ); return undefined; }
这工作正常,期望我可以看到它在我的所有应用程序中触发滚动更改检测.
这是我的一个组件内部:
private aFunction () { console.log( 'change detected !!!' ); }
我在某个组件中的某个模板中有一个函数:
<div>{{ aFunction() }}</div>
以前,只有当我更新了一些输入或点击了一个按钮时,aFunction才会被解雇,但是现在,它正在滚动变换检测!
因此,我的滚动体验是滞后的!
这是Angular2的正常行为,所有事件都应该触发更改检测,但我想从此规则中排除我的滚动事件.
简而言之,如何在Angular2中定义一个事件,并将其转换为触发变更检测并使其成为手动的能力.
我在找 :
this.renderer.listenGlobalButDontFireTheChangeDetection
我可以为你提供几个黑客:
1)只需在组件的OnPush上设置检测策略:
@Component({ ... changeDetection: ChangeDetectionStrategy.OnPush })
相应的plunkr在这里是http://plnkr.co/edit/NPHQqEmldC1z2BHFCh7C?p=preview
2)将zone.runOutsideAngular与本机window.addEventListener一起使用:
this.zone.runOutsideAngular(() => { window.addEventListener('scroll',(e)=> { console.log( 'scrolling' ); }); });
另见plunkr http://plnkr.co/edit/6Db1AIsTEGAirP1xM4Fy
3)使用zone.runOutsideAngular和EventManager的新实例,如下所示:
import { DomEventsPlugin,EventManager } from '@angular/platform-browser'; ... this.zone.runOutsideAngular(() => { const manager = new EventManager([new DomEventsPlugin()],new NgZone({enableLongStackTrace: false})); manager.addGlobalEventListener('window',(e) => { console.log( 'scrolling' ); }); });
plunkr在这里http://plnkr.co/edit/jXBlM4fONKSNc7LtjChE?p=preview
我不确定这是正确的做法.也许它可以帮助你推进… 原文链接:https://www.f2er.com/angularjs/142439.html