2016-05-19 33 views
10

我結合的滾動事件捕捉滾動並用它做什麼,我創建了一個指令,像波紋管:防止原生瀏覽器事件(如滾動)燒製而成變化檢測

所以我必須簡單指令,它有什麼,但:

 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 !!!'); 
    } 

我在模板中有aFunction地方在一些組件:

 <div>{{ aFunction() }}</div> 

此前,aFunction被炒魷魚了,只有當我更新了一些輸入或點擊一個按鈕,但現在,它正在滾動的變化檢測!因此,我的滾動體驗是滯後的!

這是Angular2的正常行爲,所有的事件都應該觸發change檢測,但我想從這條規則中排除我的滾動事件。

簡而言之,如何在Angular2中定義一個事件,並轉化爲觸發變化檢測並使其成爲手動的能力。

我在尋找:

this.renderer.listenGlobalButDontFireTheChangeDetection 

回答

10

我可以爲您提供幾個黑客這樣做:

1)只要設置檢測策略,以OnPush您的組件上:

@Component({ 
    ... 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 

相應的plunkr在這裏http://plnkr.co/edit/NPHQqEmldC1z2BHFCh7C?p=preview

2)使用區域。 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','scroll', (e) => { 
    console.log('scrolling'); 
    }); 
}); 

的plunkr是這裏http://plnkr.co/edit/jXBlM4fONKSNc7LtjChE?p=preview

我不確定這是否正確。也許它可以幫助你在前進... :)

更新:在這個問題上

答:View is not updated on change in Angular2給了我一個想法,第三解決方案。 第二種解決方案正在工作,因爲窗口是在角度區域之外創建的。你不能這樣做:

this.zone.runOutsideAngular(() => { 
    this.renderer.listenGlobal('window' , 'scroll' ,()=> { 
     console.log('scrolling'); 
    }); 
}); 

它不會工作,因爲this.renderer是在角度區內創建的。 http://plnkr.co/edit/UKjPUxp5XUheooKuKofX?p=preview

我不知道如何創建一個新的實例Renderer(在我們的例子中是DomRenderer),所以我只是在工作區域之外和新的實例NgZone創建了新的實例EventManager。

+0

謝謝隊友,我不能使用第一個,因爲我不想改變我所有的組件變更檢測策略,第二個和第三個看起來完全像我想要的,請你詳細說明他們嗎?他們有什麼不同? – Milad

+0

這解決了我的問題,第二和第三都工作正常,有什麼區別? 我想使用Renderer使我的代碼web工作人員友好,您的答案更像是使用Renderer,爲什麼?你能解釋一下嗎? – Milad

+0

是的,我會盡快寫出 – yurzui

相關問題