2016-05-11 17 views
14

Angular 2'de, angular2/http modülünü kullanarak ajax çağrısının ilerlemesini (yani yüzde yüzdeyi) almak için bir yol var mı?Köşeli 2 HTTP İlerleme çubuğu

benim HTTP aramaları yapmak için şu kodu kullanın:

 let body = JSON.stringify(params); 
     let headers = new Headers({ 'Content-Type': 'application/json' }); 
     let options = new RequestOptions({ headers: headers }); 
     this.http.post(url, body, options) 
      .timeout(10000, new Error('Timeout exceeded during login')) 
      .toPromise() 
      .then((res) => { 
       ... 
      }).catch((err) => { 
       ... 
      }); 

amacı bir senkronizasyon sistemi yazmaktır. Gönderi çok fazla veriyi döndürecek ve kullanıcıya senkronizasyonun ne kadar süreceği konusunda bir gösterge vermek istiyorum.

cevap

6

XHR tarafından sağlanan onprogress etkinliğinden yararlanabilirsiniz (bkz. Bu plunkr: http://plnkr.co/edit/8MDO2GsCGiOJd2y2XbQk?p=preview).

Bu, yüklemenin ilerleyişi hakkında ipuçları almanızı sağlar. Bu Angular2 tarafından kutunun dışında desteklenmiyor ancak genişletilmiş BrowserXhr sınıfı tarafından takın edebilirsiniz:

@Injectable() 
export class CustomBrowserXhr extends BrowserXhr { 
    constructor(private service:ProgressService) {} 
    build(): any { 
    let xhr = super.build(); 
    xhr.onprogress = (event) => { 
     service.progressEventObservable.next(event); 
    }; 
    return <any>(xhr); 
    } 
} 

ve genişletilmiş ile BrowserXhr sağlayıcı geçersiz:

bootstrap(AppComponent, [ 
    HTTP_PROVIDERS, 
    provide(BrowserXhr, { useClass: CustomBrowserXhr }) 
]); 

daha bu soruya bakın ayrıntıları:

+0

XHRRequest :) ile uygulamadan kaçınabileceğimi umuyordum ama bu konuda yapacak bir şey yok;) –

+0

Aslında, Angular2'nin HTTP desteğinde desteklenmiyor (bu nedenle), XHR ... –

3

Açısal2'de http değişkeni yaptığınızda, Gözlemlenebilir türden bir Yanıtı döndürür, bu yanıt tüm sihirin gerçekleştiği XHRConnection sınıfında oluşturulur.

XHRConnection, XMLHttpRequest'in yükleme olayını dinleyerek yanıtı oluşturur; bu, isteğin sonunda bir yanıt döndüreceği anlamına gelir. Şimdi

bizim bağlantı sınıfı ilerleme olay dinlemek yapmak gerekir bu davranışı değiştirmek mümkün.

Bu nedenle, uygun gördüğümüz yanıtı ele almak için özel Bağlantı sınıfı oluşturmamız gerekiyor.

Ben bu şekilde yaptım, Benim php API'mn tek bir istekte çok yanıt verdiğini ve bu yanıtların düz dizeler olduğunu unutmayın.

my_backend.ts

import {Injectable} from "angular2/core"; 
import {Observable} from "rxjs/Observable"; 
import {Observer} from "rxjs/Observer"; 
import {Connection,ConnectionBackend} from "angular2/src/http/interfaces"; 
import {ReadyState, RequestMethod, ResponseType} from "angular2/src/http/enums"; 
import {ResponseOptions} from "angular2/src/http/base_response_options"; 
import {Request} from "angular2/src/http/static_request"; 
import {Response} from "angular2/src/http/static_response"; 
import {BrowserXhr} from "angular2/src/http/backends/browser_xhr"; 
import {Headers} from 'angular2/src/http/headers'; 
import {isPresent} from 'angular2/src/facade/lang'; 
import {getResponseURL, isSuccess} from "angular2/src/http/http_utils" 

export class MyConnection implements Connection { 
    readyState: ReadyState; 
    request: Request; 
    response: Observable<Response>; 

    constructor(req: Request, browserXHR: BrowserXhr, baseResponseOptions?: ResponseOptions) {  
     this.request = req; 
     this.response = new Observable<Response>((responseObserver: Observer<Response>) => { 
      let _xhr: XMLHttpRequest = browserXHR.build(); 
      _xhr.open(RequestMethod[req.method].toUpperCase(), req.url); 
      // save the responses in array 
      var buffer :string[] = []; 
      // load event handler 
      let onLoad =() => { 
       let body = isPresent(_xhr.response) ? _xhr.response : _xhr.responseText; 
       //_xhr.respons 1 = "Loading data!" 
       //_xhr.respons 2 = "Loading data!Ready To Receive Orders." 
       // we need to fix this proble 
       // check if the current response text contains the previous then subtract 
       // NOTE: I think there is better approach to solve this problem. 
       buffer.push(body); 
       if(buffer.length>1){ 
        body = buffer[buffer.length-1].replace(buffer[buffer.length-2],''); 
       } 
       let headers = Headers.fromResponseHeaderString(_xhr.getAllResponseHeaders()); 
       let url = getResponseURL(_xhr); 
       let status: number = _xhr.status === 1223 ? 204 : _xhr.status; 
       let state:number = _xhr.readyState; 
       if (status === 0) { 
        status = body ? 200 : 0; 
       } 
       var responseOptions = new ResponseOptions({ body, status, headers, url }); 
       if (isPresent(baseResponseOptions)) { 
        responseOptions = baseResponseOptions.merge(responseOptions); 
       } 
       let response = new Response(responseOptions); 
       //check for the state if not 4 then don't complete the observer 
       if(state !== 4){ 
        //this will return stream of responses 
        responseObserver.next(response); 
        return; 
       } 
       else{ 
        responseObserver.complete(); 
        return; 
       } 
       responseObserver.error(response); 
      }; 
      // error event handler 
      let onError = (err: any) => { 
       var responseOptions = new ResponseOptions({ body: err, type: ResponseType.Error }); 
       if (isPresent(baseResponseOptions)) { 
        responseOptions = baseResponseOptions.merge(responseOptions); 
       } 
       responseObserver.error(new Response(responseOptions)); 
      }; 

      if (isPresent(req.headers)) { 
       req.headers.forEach((values, name) => _xhr.setRequestHeader(name, values.join(','))); 
      } 
      _xhr.addEventListener('progress', onLoad); 
      _xhr.addEventListener('load', onLoad); 
      _xhr.addEventListener('error', onError); 

      _xhr.send(this.request.text()); 

      return() => { 
       _xhr.removeEventListener('progress', onLoad); 
       _xhr.removeEventListener('load', onLoad); 
       _xhr.removeEventListener('error', onError); 
       _xhr.abort(); 
      }; 
     }); 
    } 
} 
@Injectable() 
export class MyBackend implements ConnectionBackend { 
    constructor(private _browserXHR: BrowserXhr, private _baseResponseOptions: ResponseOptions) {} 
    createConnection(request: Request):MyConnection { 
    return new MyConnection(request, this._browserXHR, this._baseResponseOptions); 
    } 
} 

Ve yılında http.get çağıran yanıtların bir buhar dönecektir

import {Component, provide} from 'angular2/core'; 
import {HTTP_PROVIDERS,XHRBackend} from 'angular2/http'; 
import {MyBackend} from './my_backend'; 
@Component({ 
    selector: 'my-app', 
    providers: [ 
     HTTP_PROVIDERS, 
     MyBackend, 
     provide(XHRBackend, {useExisting:MyBackend}) 
    ] 
    . 
    . 
    . 

Şimdi app.component.ts.

1

şiddetle oturumları çerezleri ve diğer maddeleri

kaçırmak yapacak bu

https://www.npmjs.com/package/angular-progress-http

aksi XHR'nin ile karıştırmasını kullanarak tavsiye daha taşınabilir ve

uygulamak için bir yol daha kolay olacak yanında
+0

Bu, Angular 5'e yükseltme yapana kadar harika çalışır ve OpaqueToken'e başvurduğu için paket başarısız olur. –

+1

Birinin kodlarını kopyalamak yerine tekniği öğrenmeyi tercih ederim – Ronit

9

Şu anda (from. 4.3.0, @ngular/common/http numaralı yeni HttpClient kullanırken) Açısal kutudan çıkıp dinlemeyi dinlemenizi sağlar. Sadece aşağıdaki gibi nesne HTTPRequest oluşturmanız gerekir:

import { HttpRequest } from '@angular/common/http'; 
... 

const req = new HttpRequest('POST', '/upload/file', file, { 
    reportProgress: true, 
}); 

Ve sen her ilerleme olayı denilen abonelik alacak istemek için abone olduğunuzda:

http.request(req).subscribe(event => { 
    // Via this API, you get access to the raw event stream. 
    // Look for upload progress events. 
    if (event.type === HttpEventType.UploadProgress) { 
    // This is an upload progress event. Compute and show the % done: 
    const percentDone = Math.round(100 * event.loaded/event.total); 
    console.log(`File is ${percentDone}% uploaded.`); 
    } else if (event instanceof HttpResponse) { 
    console.log('File is completely uploaded!'); 
    } 
}); 

diğer bilgiler here.