2016-07-14 134 views
7

我無法獲得一些觀察對象。我似乎無法得到兩個 observables放置在一起。他們自己的工作很好,但我 需要兩個值。Angular2合併觀察對象

db.glass.subscribe((glass: GlassData[]): void => { 
    console.log(glass); // This prints 
}); 

db.cassette_designs.subscribe((cassettes: CassetteData[]): void => { 
    console.log(cassettes): // This prints 
}); 

由於不是所有熟悉的觀測,我想的第一件事是 嵌套在另一個內,但內一個似乎並沒有做任何事情。

db.glass.subscribe((glass: GlassData[]): void => { 
    console.log(glass); // This prints 

    db.cassette_designs.subscribe((cassettes: CassetteData[]): void => { 
    console.log(cassettes): // This doesn't 
    }); 
}); 

這似乎有點傻成這樣我搜索在谷歌,看看是否有一個 更好的方法來觀測結合起來,原來有幾個。我試過 zipforkJoin,因爲他們看起來最喜歡我想做的事情,但是 也沒有什麼能與他們一起工作。

Observable.zip(db.cassette_designs, db.glass, (cassettes: CassetteData[], glass: GlassData[]): void => { 
    console.log(cassettes); // doesn't print 
    console.log(glass ); // doesn't print 
}); 

Observable.forkJoin([ db.cassette_designs, db.glass ]).subscribe((data: any): void => { 
    console.log(data); // doesn't print 
}); 

這可能是這樣簡單的事情,因爲我沒有正確調用功能,但 我還以爲我會得到某種形式的警告或錯誤的在某些時候。 tsc 沒有任何代碼問題,我在Chrome或Firefox上的開發人員 控制檯中沒有收到任何消息。

更新

我試過combineLatest,但它仍然不會顯示在控制檯東西。我一定錯過了一些東西,但我不確定是什麼。他們單獨工作。

Observable.combineLatest(db.cassette_designs, db.glass, (cassettes: CassetteData[], glass: GlassData[]): void => { 
    console.log(cassettes); // doesn't print 
    console.log(glass ); // deson't print 
}); 

的觀測是創建方式如下:

... 

public Listen(event: string): Observable<Response> 
{ 
    return new Observable<Response>((subscriber: Subscriber<Response>): Subscription => { 
    const listen_func = (res: Response): void => subscriber.next(res); 

    this._socket.on(event, listen_func); 

    return new Subscription((): void => 
     this._socket.removeListener(event, listen_func)); 
    }); 
} 

... 

然後真正得到我派人對有關事件響應的監聽觀測。例如

... 

public cassette_designs: Observable<CassetteData[]>; 

... 

this.cassette_designs = _socket.Listen("get_cassette_designs") 
    .map((res: Response) => res.data.data); 
+0

SO好奇你的項目是什麼!卡帶和玻璃,他們都在一起玩!愛它! –

+1

這是一個允許用戶設計門的在線工具。 – Hector

回答

9

我設法讓combineLatest工作,通過實際訂閱產生的 observable。

本來我是這樣做的:

Observable.combineLatest(db.cassette_designs, db.glass, (cassettes: CassetteData[], glass: GlassData[]): void => { 
    console.log(cassettes); 
    console.log(glass ); 
}); 

現在我這樣做:

Observable.combineLatest(db.cassette_designs, db.glass).subscribe((data: any[]): void => { 
    console.log(data); 
    // cassettes - data[0] 
    // glass  - data[1] 
}); 
1

嘿如果要具有發射的2個源的組合的數據的單個流(觀察到的),檢查出combineLatest方法。

1

二者:Observable.zip和Observable.forkJoin都必須工作。 (就我個人而言,我更喜歡'forkJoin' - 它返回的數組與相同的順序,因爲你推送observables,並且你不需要大量的參數)

也許,如果您手動創建observables(Observable.create ...),你只是忘了從'create'方法中爲兩個提供的Observers調用'completed'。

6

當您發現跟進:

1)Observable是一個懶惰的執行數據類型,這意味着它不會在管道中執行任何事情,直到它訂閱。這也適用於組合運算符。 zip,forkJoin,combineLatestwithLatestFrom將全部遞歸地訂閱Observables,你在之後只通過他們他們自己有訂閱。

因此:

var output = Observable.combinelatest(stream1, stream2, (x, y) => ({x, y})); 

實際上不會做任何事情,直到你打電話output.subscribe(),此時subscribe也呼籲stream1stream2,你會得到Rx的所有魔法。

2)更小的一點,但每當你開始做自己的創建方法時,首先查看文檔以查看它是否已經存在。有靜態創建方法,Arrays,Promises,節點式回調和是偶標準event patterns

因此您的Listen方法可以成爲:

public Listen<R>(event: string): Observable<R> { 
    return Observable.fromEvent(this._socket, event); 
} 
+0

這很有道理。關於我得到的可觀察性的方式,我按照自己的方式進行操作的主要原因是確保從observable退訂也會刪除該聽衆。我會看看文檔,看看我能找到什麼。 – Hector

0

我用combineLatest。我需要三個調用API,但我只需要一個組合這三個響應的對象。

我跟着這個相同的帖子中提到的公式:

var output = Observable.combinelatest(stream1, stream2, (x, y) => ({x, y})); 

作爲最終代碼:

getGobalStats(): Observable<any> { 

    let obs1 = this._http.get(this._config.getGlobalStatsUrl(), this._config.getOptions()) 
     .map((res: Response) => { 
     return res.json().content; 
     }) 
     .catch((error: any) => { console.error(error); return error; }); 
    let obs2 = this._http.get(this._config.getGlobalStatsUrl() + '?type=1', this._config.getOptions()) 
     .map((res: Response) => { 
     return res.json().content; 
     }) 
     .catch((error: any) => { console.error(error); return error; }); 
    let obs3 = this._http.get(this._config.getGlobalStatsUrl() + '?type=3', this._config.getOptions()) 
     .map((res: Response) => { 
     return res.json().content; 
     }) 
     .catch((error: any) => { console.error(error); return error; }); 

     return Observable.combineLatest(obs1,obs2,obs3,(res1,res2,res3) => { return {all:res1,running: res2, cycling: res3}}); 
    } 
0
 Observable.merge(
      Observable.fromEvent(canvasEl, 'mousedown'), Observable.fromEvent(canvasEl, 'touchstart')) 
      .switchMap((e) => { 
       return Observable.merge(
        Observable.fromEvent(canvasEl, 'mousemove').takeUntil(Observable.fromEvent(canvasEl, 'mouseup')), 
        Observable.fromEvent(canvasEl, 'touchmove').takeUntil(Observable.fromEvent(canvasEl, 'touchend')), 
       ) 
        .pairwise() 
      }) 
      .subscribe(...