首页 > 解决方案 > 在 Angular6 中使用 Observables 更改参数的 Api 服务

问题描述

我想要的行为:当用户从下拉菜单中选择标签时,使用该标签作为参数调用 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 调用 -> 重绘图表。那么如何正确地做呢?

标签: angulartypescriptrxjs

解决方案


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

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;
}

推荐阅读