使用Angular6中的Observables更改参数的Api服务

时间:2018-08-21 09:12:17

标签: angular typescript rxjs

我想要的行为:当用户从下拉菜单中选择“标签”时,以该Label作为参数调用api,并使用从api接收的数据重绘图表。页面中有多个相同的图表,并带有各自的下拉列表。 问题是我的解决方案不起作用,我不确定如何使它起作用。我的解决方案:

图表组件

export class ChartComponent implements OnInit, OnDestroy{

    private _label = new ReplaySubject<string>()
    //Gets value from dropdown menu
    @Input() set label(value: string) {this._label.next(value)}

    apiSub: Subscription

    constructor(private apiService: ApiService) {
    }

    ngOnInit() {
        this.apiSub = this.apiService
        .getData(this._label)
        .subscribe(this.redrawGraph.bind(this),
            console.error
        )
    }

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

    redrawGraph(data:Data[]){
        //Chart drawing logic
    }
}

Api服务

export class ApiService {

    response= new ReplaySubject<Observable<Data[]>>()

    constructor(private http: HttpClient) {
    }

    private static _handleError(err: HttpErrorResponse | any) {
        return Observable.throw(err.message || 'Error: Unable to connect to API.');
    }


    getData( label: Observable<string> ): Observable<Data[]> {
        label.subscribe(label => {
            this.response.next(this.http
            .get<Data[]>(`${Urls.DATA}?label=${label}`)
            .catch(ApiService._handleError));
        })

        return this.response.mergeMap(x => x)
    }

现在,只有在第一次标签更改时才调用redrawGraph()。而且,当存在多个图形时,显然存在不良行为,因为据我所知,服务是单例的,但是我不知道如何将响应绑定到“ this”而返回响应。

我要避免的是每次标签更改时都必须从Chart组件订阅/取消订阅api方法,而只需要一个流:标签更改-> api调用->重新绘制图表。那么如何正确执行呢?

1 个答案:

答案 0 :(得分:0)

要使其生效,您需要为每个图表创建一个单独的主题。 该代码将如下所示:

getData( label: Observable<string> ): Observable<Data[]> {
    let response : Subject = Subject<Data[]>();
    label.subscribe(label => {
        response.next(this.http
        .get<Data[]>(`${Urls.DATA}?label=${label}`)
        .catch(ApiService._handleError));
    })

    return response;
}