Angular 在Http请求上加载指示符

Angular 在Http请求上加载指示符,angular,typescript,rxjs,typescript1.8,Angular,Typescript,Rxjs,Typescript1.8,我的问题的根源是在http请求上显示加载指示器,我希望在服务级别上这样做,而不必为每个组件编写代码。我所做的是实现一个http包装器,它基本上实现了以下功能: getMyHttpObservable(...) { setLoadingIndicator(true); const myHttpObservable = createRequestObservable().finally(()=> { console.log('http

我的问题的根源是在http请求上显示加载指示器,我希望在服务级别上这样做,而不必为每个组件编写代码。我所做的是实现一个http包装器,它基本上实现了以下功能:

getMyHttpObservable(...) {
    setLoadingIndicator(true);
    const myHttpObservable = 
        createRequestObservable().finally(()=> {
            console.log('http done');
            setLoadingIndicator(false);
        });
    return myHttpObservable;
}
我有一个观察序列,我使用
Observable.concat
链接如下:

const t1 = Observable.timer(5000).finally(()=>console.log('t1 done'));
const t2 = getMyHttpObservable(...);
const agg = Observable.concat(t1,t2);
const ev = new EventEmitter<any>();
const cancellableAgg = agg.takeUntil(ev.asObservable());
getMyHttpObservable(...) {
    const myHttpObservable = createRequestObservable(...);
    const subscriptionAware = new Observable(subscriber => {
        setLoadingIndicator(true);
        myHttpObservable.subscribe(
            nextEv => subscriber.next(nextEv),
            errEv => subscriber.error(errEv),
            () => subscriber.complete())
        .add(()=>setLoadingIndicator(false));
    };
    return subscriptionAware;
}
我使用基于事件的取消技术,使用
Observable.takeUntil
,如下所示:

const t1 = Observable.timer(5000).finally(()=>console.log('t1 done'));
const t2 = getMyHttpObservable(...);
const agg = Observable.concat(t1,t2);
const ev = new EventEmitter<any>();
const cancellableAgg = agg.takeUntil(ev.asObservable());
getMyHttpObservable(...) {
    const myHttpObservable = createRequestObservable(...);
    const subscriptionAware = new Observable(subscriber => {
        setLoadingIndicator(true);
        myHttpObservable.subscribe(
            nextEv => subscriber.next(nextEv),
            errEv => subscriber.error(errEv),
            () => subscriber.complete())
        .add(()=>setLoadingIndicator(false));
    };
    return subscriptionAware;
}
当以上操作运行时,我得到以下输出:

t1 done
我还需要完成
http
,以便清除加载指示器。我怎样才能做到这一点

谢谢

编辑

我没有意识到,
concat
操作符只在它们的前辈已经完成时订阅后续的可观测值。我需要的是仅当http observable实际已订阅时才激活我的加载指示器

我修改了包装器函数,如下所示:

const t1 = Observable.timer(5000).finally(()=>console.log('t1 done'));
const t2 = getMyHttpObservable(...);
const agg = Observable.concat(t1,t2);
const ev = new EventEmitter<any>();
const cancellableAgg = agg.takeUntil(ev.asObservable());
getMyHttpObservable(...) {
    const myHttpObservable = createRequestObservable(...);
    const subscriptionAware = new Observable(subscriber => {
        setLoadingIndicator(true);
        myHttpObservable.subscribe(
            nextEv => subscriber.next(nextEv),
            errEv => subscriber.error(errEv),
            () => subscriber.complete())
        .add(()=>setLoadingIndicator(false));
    };
    return subscriptionAware;
}
因此,基本上,我正在创建一个
可观察的
,它透明地包装另一个
可观察的
,但在实际订阅时还执行一些额外的操作-激活加载指示器

然而,现在我已经失去了在飞行中取消XHR请求的能力,因为
Observable
的构造函数不允许我传递取消处理程序,所以内部订阅永远不会被取消


关于如何实现这一点,有什么想法吗?

使用内置的
延迟
操作符找到了一个解决方案,该操作符等待订阅并返回一个新的可观察值:

getMyHttpObservable(...) {
    const myHttpObservable = createRequestObservable(...);
    return Observable.defer(() => {
        setLoadingIndicator(true);
        return myHttpObservable.finally(() => setLoadingIndicator(false));
    });
}

优雅而简短。

我建议采用另一种方法,即定义一个装饰器,将其应用于需要设置微调器的方法。将微调器放在http级别不够灵活,会将网络逻辑与UI IMHO混淆。