2016-09-23 8 views
2

私は私のajax呼び出しに基づいて塗りつぶす正確なプログレスバーを作ろうとしています。角2.0プログレスバーを作成するためにBrowserXhrを拡張する方法は?

This助けられましたが、おそらく書かれてから少し変わったと思います。

だから、私はBrowserXhrをovverrideするために私のアプリモジュール・プロバイダーに追加した私のCustomBrowserXhr持っている: - :

- 私は、他のコンポーネントが購読することができ、非常に基本的な進行状況のサービスを持っている

@Injectable() 
export class CustomBrowserXhr extends BrowserXhr { 

constructor(private service: ProgressService) {} 


    build(): any { 
     let xhr = super.build(); 
     xhr.onprogress = (event) => { 
      console.log(event, "event inside browser override"); 
      this.service.progressEventObservable.next(event); 
     }; 
     return <any>(xhr); 
    } 
} 

私はhttpコールを発信できると思っていましたが、コンソールログの「ブラウザ内オーバーライドイベント」が表示されることがありましたが、「例外:browserXHR.buildは関数ではありません」というエラーが表示されます。誰かが何らかの光を当てることができますかここで間違っているのはどうですか?

ありがとうございます。

+0

解決策を見つけられましたか? – kmansoor

+0

@kmansoor申し訳ありませんが、私は期限があったので、私は上に移動したので、それは素晴らしいことでした。あなたがそれをクラックすれば教えてください:) –

+0

本当にありがとう、 'ProgressServcie'が正しくCustomBrowserXhrのコンストラクタに注入されたかどうか教えていただけますか?私は同様の設定をしていますが、ProgressServiceの注入は失敗しています。どうも。 – kmansoor

答えて

2

編集:私は​​への呼び出しを追加し、イベントオブジェクトにいくつかの便利なことを付けました。

ありがとうございました。これは私のために働く。私は簡潔にするために一つのファイルにこれらのサービスの両方を投げた:

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

私はあなたが説明したのと同様に、私のメインモジュールに2つのサービスを追加しました:

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

予想通りそれはコンソールに記録しました。その後、私はファイルをアップロードコンポーネントでは、私が変更検出を強制しなければならなかったが、それはそうでない場合は正常に動作します:

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

私はそれが非同期パイプで動作するように取得しようとしたが、それが唯一の最後のイベントに更新されました。どう思いますか?

+0

私にはうまく見えますが、CustomBrowserXhrコンストラクタで 'super();'コールが必要だと思いますが、それ以外は私のために働きます。私は 'xhr.upload.onprogress'を' xhr.onprogress'に変更しました。なぜなら、私はすべてのxhr呼び出しの進捗状況を知りたいからです。 –

+0

IDEはsuper()を要求します。コール。これは、使用するかどうかで動作します。私はそれを呼び出すか否かのペナルティが何であるかを確認することはしていないが、今週はそのことを計画している。 – wolfhoundjesse

+1

これは単なる良い習慣であり、この特定のユースケースで害を及ぼすものではありません。 –

関連する問題