用于HTTP请求的ng2-slim-loading-bar

时间:2017-02-11 03:19:50

标签: angular typescript

我需要使用ng2-slim-loading-bar来显示从后端获取请求时的进度。

这是我的组件。

ngOnInit(){
        this._slimLoader.start();
        this._productsAdminService.getProducts()
            .subscribe(products => {
                products.forEach(function(product){
                    if(product.cat_id === 1) product.catName = 'Dota Shirts';
                    if(product.cat_id === 2) product.catName = 'Gym Shirts';
                    if(product.cat_id === 3) product.catName = 'Car Shirts';
                });
                this.products = products;
                console.log(this.products);
                this._slimLoader.complete();
            },
            err => console.log(err));
    }

这个请求应该需要3-5秒才能解决,所以我需要让进度条像这样加载。这里的问题是,当我加载页面时,在回调完成之前不会显示任何内容。显示我的所有产品后,它会立即显示然后消失。

这里有什么不对吗?请帮忙。

2 个答案:

答案 0 :(得分:0)

我过去也遇到过同样的问题。当您使用this._slimLoader.start();时,它会从0%开始加载条形图并且缓慢递增。这意味着您无法在视觉上看到它,因为它位于浏览器的边缘。

您可以将进度设置为特定百分比,而不是使用.start(),例如this._slimLoader.progress = 70;,然后在请求完成后致电.complete();

我相信YouTube会使用这种风格。

答案 1 :(得分:0)

正如Todo的回答所提到的,酒吧从0%开始。您需要将其设置为20%并致电start()。但是,start()只会在某个时间间隔内递增,当它达到100%时,条形图会消失,错误地指示加载已完成。如果start()接受每个步骤调用的回调,那么你可以将其停止在90%。但事实并非如此。

所以这就是我在项目中所做的(Red Hat Automated Migration Toolkit):

  • 在我们的HTTP服务包装器(处理OAuth)中,我们触发一个事件,
  • 然后由我们LoadingIndicatorService抓住。
  • LoadingIndicatorService
    • 包裹SlimLoaderBarService
    • 并跟踪正在进行的HTTP请求数量。
    • 然后它计算百分比并将其放在20%到90%的范围内。
    • 当所有HTTP请求完成后,它会保持90%大约一秒钟,然后调用complete()

如果您对每个导航步骤有多个请求,这看起来很自然,并提供了良好的用户体验。 如果您通常只有1个请求,那么您可能想要调整基于CSS的动画(使其更长)或者使用start() afterall。

以下是一些关键代码部分:

@Injectable()
export class LoadingIndicatorService {

    constructor(
        private _slimBarService: SlimLoadingBarService,
        private _eventBusService: EventBusService,
    ) {
        // Register the LoadingSomething event listeners.
        this._eventBusService.onEvent
            .filter(event => event.isTypeOf(LoadingSomethingStartedEvent))
            .subscribe((event: LoadingSomethingStartedEvent) => this.loadingStarted() )
        this._eventBusService.onEvent
            .filter(event => event.isTypeOf(LoadingSomethingFinishedEvent))
            .subscribe((event: LoadingSomethingFinishedEvent) => this.loadingFinished() )
    }

    public getSlimService(){
        return this._slimBarService;
    }


    private counter: number = 0;
    private max: number = void 0;

    private reset() {
        this.counter = 0;
        this.max = void 0;
    }

    public loadingStarted(){
        this.counter++;
        this.max = this.counter;
        this.updateProgress();
    }

    public loadingFinished(){
        this.counter--;
        this.updateProgress();
    }

    private updateProgress() {
        if (this.counter == 0) {
            this._slimBarService.height = "2px";
            this._slimBarService.visible = true;
            this._slimBarService.progress = 95;
            this.max = void 0;
            Observable.timer(700).subscribe(() => {
                this._slimBarService.complete();
            });
        }
        else {
            // max - counter = finished.
            // If the things to load are added after something loaded, the progress would go back.
            // But let's rely on that loading will start fast at the beginning.
            // Start at 20, jump to 90.
            let percent = 20 + 70 * (1 - (this.max - this.counter) / this.max);
            this._slimBarService.height = "3px";
            this._slimBarService.color = "#39a5dc";
            this._slimBarService.visible = true;
            this._slimBarService.progress = percent;
        }
    }

}


    let responseObservable2 = responseObservable.do(
        () => console.log("Request SUCCEEDED"),
        () => console.log("Request FAILED"),
        () => {
            console.log("Request FINISHED");
            if (this._eventBus) {
                console.log("Request FINISHED, firing");
                this._eventBus.fireEvent(new LoadingSomethingFinishedEvent(responseObservable))
            }
        }
    );

HTTP服务包装器:

@Injectable()
export class WindupHttpService extends Http {

    private configureRequest(method: RequestMethod, f: Function, url: string | Request, options: RequestOptionsArgs = {}, body?: any): Observable<Response> {
        let responseObservable: Observable<Response> = ...

    ...

    console.log("Load STARTED");
    if (this._eventBus)
        console.log("Load STARTED, firing");
    this._eventBus.fireEvent(new LoadingSomethingStartedEvent(responseObservable));

    return responseObservable2;
}

有关完整代码,请搜索github.com以获取项目Windup。