2016-07-14 132 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(...