2016-11-13 74 views
0

我有一个模式来了很多,我不是什么是解决它的最佳方法。如何避免订阅汤?

我订阅了一个observable(这里是路由器),它给了我值。我需要这些值中的一个来构建另一个请求来获得另一个可观察值。但是我有一个观察者在订阅。

我知道这不是一个好的模式,但我不知道该怎么做。

如果我使用这第二个可观察值来获取另一个值并获得另一个可观察的观察值。

如何解决这个问题,避免汤?

这里是我的代码:

deal.component.ts

import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; 
import {Observable} from "rxjs/Observable"; 
import {ActivatedRoute} from "@angular/router"; 
import {DealsService} from "../deals.service"; 

@Component({ 
    templateUrl: './+deal.component.html', 
    styleUrls: ['./+deal.component.scss'] 
}) 
export class DealRouterComponent implements OnInit { 

    deal$: Observable<any>; 
    public dealId:string; 
    private sub:any; 

    constructor(
    private route: ActivatedRoute, 
    private dealsService: DealsService) {} 

    ngOnInit() { 
    this.sub = this.route.params 
     .subscribe(params => { 
     this.dealId = params['id']; 
     this.deal$ = this.dealsService.getDeal(this.dealId); 
     }) 
    } 

    ngOnDestroy() { 
    this.sub.unsubscribe(); 
    } 

} 

deal.service.ts

import {Injectable, Inject} from "@angular/core"; 
import {Observable} from "rxjs/Observable"; 
import {AngularFireDatabase} from "angularfire2"; 

@Injectable() 
export class DealsService { 

    constructor(private db: AngularFireDatabase) {} 

    getDeal(id) { 
    return this.db.object('deals/' + id); 
    } 

} 

deal.component.html

{{deal | async | json}} 
+2

这种模式类似于嵌套的'承诺地狱'。解决方案是用mergeMap(flatMap)运算符链接可观察对象。 – estus

回答

3

可观察的可通过operators链接。这是可观察的优势之一,我发现this tutorial是解释如何使用ReactiveX最好的解释之一。

你不应该像你为deal$那样改变观察。假设你的服务只是从一个ID返回一笔交易,那么你的交易就是Observable,而我假设你想要的是一个Observable,它会随着时间的推移发出交易。你也必须不断重新订阅新的deal$。以前的Subscription将继续收听旧的deal$并永远不会获得新的值。

export class DealRouterComponent implements OnInit { 

    ngOnInit() { 
    this.deal$ = this.route.params.flatMap(params => 
     this.dealsService.getDeal(this.dealId = params['id']) 
    ); 
    } 
} 

这样,每一次路由的PARAMS得到更新deal$会散发出一种新的交易从服务。

+0

谢谢。你的回答确实帮助我理解了这一点。 – Tom