2016-02-10 39 views
5

我正在使用Angular 2來製作一個指令。我有以下事件綁定到主機組件:Angular 2 RxJS檢查延遲後的鼠標事件是否仍然有效

host: { 
    '(mouseenter)': 'onMouseEnter($event)', 
    '(mouseleave)': 'onMouseLeave($event)' 
} 

我還創建了有關該指令的兩個流和聽衆來管理這兩個事件

export class PopupDirective { 
    private _mouseEnterStream: EventEmitter<any> = new EventEmitter(); 
    private _mouseLeaveStream: EventEmitter<any> = new EventEmitter(); 

    onMouseEnter($event) { 
     this._mouseEnterStream.emit($event); 
    } 

    onMouseLeave($event) { 
     this._mouseLeaveStream.emit($event); 
    } 
} 

我想我subscribe只能被稱爲如果mouseenter事件在固定延遲後仍然有效(即,沒有發生mouseleave)。我試過這樣做,但它不起作用(這是有道理的,我只是不知道如何解決它)。

this._mouseEnterStream.flatMap((e) => { 
    return Observable 
    .of(e) 
    .takeUntil(this._mouseLeaveStream); 
}).delay(2000).subscribe(
() => console.log('yay, it worked!') 
); 

有誰有角2/RxJS經驗,知道應該怎麼處理這個?

+0

哪裏'this._mouseStream'從何而來? –

+0

@GünterZöchbauer對不起,應該是mouseEnterStream – Harangue

+0

順便說一句,因爲你使用Rx,你真的不需要EventEmitters。只需使用主題。有點驚訝,你可以使用EventEmitters作爲Observables,也許ng2將它們轉化爲引擎蓋。 – kakigoori

回答

4

Günter的答案正是你所期望的,但你應該使用of而不是return而不存在。

this._mouseEnterStream.flatMap((e) => { 
    console.log('_mouseEnterStream.flatMap'); 
    return Observable 
     .of(e) 
     .delay(2000) 
     .takeUntil(this._mouseLeaveStream); 
}).subscribe(
    (e) => { 
    console.log('yay, it worked!'); 
    console.log(e); 
    } 
); 

查看相應的plunkr:https://plnkr.co/edit/vP3xRDXxFanqzLEKd3eo?p=preview

否則,在Angular2 github上的建議簡單地使用RX位於DOM事件附加obsersables方式:https://github.com/angular/angular/issues/4062

+0

如果它只是你想要返回的單個值,'.just'更有意義。但對非Haskelly-lang用戶來說,這可能是胡言亂語。 – kakigoori

+1

感謝您的評論,但該操作符不存在Rxjs 5.0.0-beta.0。看到這個錯誤:'Rx_1.Observable.just不是函數' –

+0

哦,對不起,看起來它已經在RxJS5 beta的遷移文檔中列出了。有點難過。 – kakigoori

3

看起來頗爲相似,How do I timeout an event in RxJS?

this.myStream = this._mouseEnterStream 
    .flatMap((e) => { 
     return Observable 
      .of(e) 
      .delay(2000) 
      .takeUntil(mouseLeaveStream); 
    }); 

myStream.subscribe((x) => { 
     console.log('onNext: ', x); 
}); 

我不使用TS或RX自己(只飛鏢),因此我不知道這是否是正確的語法,或者如果運營商的名稱與這些可用於Angular的相匹配。

+1

有趣的是我在做這篇文章之前就已經嘗試了這個選項 - 但由於某些原因,.susbcribe需要連接到.flatMap才能使其工作 - 否則「next」會立即在mouseenter事件中觸發。 – Harangue