Angular 2.0 How to Extend BrowserXhr to create progress bar?

前端 未结 1 1135
礼貌的吻别
礼貌的吻别 2021-01-22 13:03

so I\'m trying to make an accurate progress bar that fills up based on the my ajax call.

This helped but I think that perhaps things have changed a little since it was w

相关标签:
1条回答
  • 2021-01-22 13:40

    Edit: I added the call to super(); and attached a few useful things to the event object.

    Thanks for your help. This works for me. I threw both of these services into one file for brevity:

    import { Injectable } from '@angular/core';
    import { BrowserXhr } from '@angular/http';
    import { Subject } from 'rxjs/Rx';
    
    @Injectable()
    export class ProgressService {
        progressEventObservable: Subject<any> = new Subject();
        progressEvent$ = this.progressEventObservable.asObservable();
    }
    
    
    @Injectable()
    export class CustomBrowserXhr extends BrowserXhr {
    
    constructor(private service: ProgressService) { super(); }
    
        build(): any {
            let xhr = super.build();
            let startTime = Date.now();
            xhr.upload.onprogress = (event) => {
                let timeElapsed = Date.now() - startTime;
                let uploadSpeed = event.loaded / (timeElapsed / 1000);
                let timeRemaining = Math.ceil(((event.total - event.loaded) / uploadSpeed));
    
                event.uploadTimeRemaining = timeRemaining;
                event.uploadSpeed = (uploadSpeed / 1024 / 1024).toFixed(2);
                event.percentCompleted = ((event.loaded / event.total) * 100).toFixed(0);
                console.log(event, "event inside browser override");
                this.service.progressEventObservable.next(event);
            };
            return <any>(xhr);
        }
    }
    

    I added the two services to my main module, just as you described:

    providers: [
        ProgressService,
        { provide: BrowserXhr, useClass: CustomBrowserXhr }
    ],
    bootstrap: [ AppComponent ]
    

    It logged to the console as expected. Then, in the component where I upload files, I had to force change detection, but it otherwise works fine:

    constructor(
    private cdr: ChangeDetectorRef,
    private service: ProgressService
    ) { 
        this.service.progressEvent$.subscribe(event => {
            this.progress = event.percentCompleted;
            this.speed = event.uploadSpeed;
            this.timeRemaining = event.uploadTimeRemaining;
            this.cdr.detectChanges();
        });
    }
    

    I tried to get it to work with async pipe, but it was only updating on the last event. What do you think?

    0 讨论(0)
提交回复
热议问题