2016-05-11 15 views
14

क्या कोणीय 2/http मॉड्यूल का उपयोग करते हुए अजाक्स कॉल की प्रगति (यानी प्रतिशत किया गया) को पुनर्प्राप्त करने के लिए वर्तमान में कोणीय 2 के भीतर एक तरीका है?कोणीय 2 HTTP प्रगति पट्टी

मैं अपने HTTP कॉल करने के लिए निम्न कोड का उपयोग करें:

 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) => { 
       ... 
      }); 

लक्ष्य एक तुल्यकालन प्रणाली लिखने के लिए है। पोस्ट बहुत सारे डेटा लौटाएगा, और मैं उपयोगकर्ता को यह संकेत देना चाहता हूं कि सिंक्रनाइज़ेशन कब तक लगेगा।

उत्तर

6

आप एक्सएचआर द्वारा प्रदान किए गए onprogress ईवेंट का लाभ उठा सकते हैं (यह प्लंकर देखें: http://plnkr.co/edit/8MDO2GsCGiOJd2y2XbQk?p=preview)।

यह डाउनलोड की प्रगति के बारे में संकेत प्राप्त करने की अनुमति देता है। यह Angular2 से बॉक्स से बाहर समर्थित नहीं है, लेकिन आप बढ़ाया BrowserXhr वर्ग द्वारा प्लग कर सकते हैं:

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

और विस्तारित साथ BrowserXhr प्रदाता ओवरराइड:

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

अधिक के लिए यह प्रश्न देखें विवरण:

+0

मुझे उम्मीद थी मैं XHRRequest साथ लागू करने से बच सकते हैं :) लेकिन कुछ भी इसके बारे में क्या करने के लिए;) –

+0

वास्तव में, यह Angular2 के HTTP समर्थन में समर्थित नहीं है (अभी तक) तो आप स्पष्ट रूप से एक्सएचआर पर भरोसा करने की जरूरत है ... –

3

जब आप कोणीय 2 में http cals बनाते हैं, तो यह एक प्रतिक्रियाशील प्रकार का प्रतिक्रिया देता है, यह प्रतिक्रिया XHRConnection नामक कक्षा के अंदर बनाई गई है जहां सभी जादू होता है।

एक्सएचआरकनेक्शन XMLHttpRequest की लोड इवेंट को सुनकर प्रतिक्रिया बनाता है, इसका मतलब है कि यह अनुरोध के अंत में एक प्रतिक्रिया वापस कर देगा।

अब इस व्यवहार हम अपने कनेक्शन वर्ग प्रगति घटना को सुनने के बनाने की जरूरत को बदलने के लिए सक्षम होने के लिए।

इसलिए हमें फिट देखने के लिए प्रतिक्रिया को संभालने के लिए कस्टम कनेक्शन कक्षा बनाने की आवश्यकता है।

मैंने इसे इस तरह से किया, ध्यान दें कि मेरा PHP एपीआई एक अनुरोध में बहु प्रतिक्रिया देता है और यह प्रतिक्रियाएं सादे तार हैं।

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

और में app.component.ts

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}) 
    ] 
    . 
    . 
    . 

अब बुला http.get प्रतिक्रियाओं का एक भाप वापस आ जाएगी।

1

मैं दृढ़ता से इस

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

अन्यथा XHR साथ चारों ओर खिलवाड़ का उपयोग कर आप सत्र कुकी और अन्य सामान

याद कर देगा की सिफारिश के अलावा यह अधिक पोर्टेबल और जिस तरह

लागू करने के लिए आसान होगा
+0

जब तक आप कोणीय 5 में अपग्रेड नहीं करते हैं तब तक यह बहुत अच्छा काम करता है और फिर पैकेज विफल रहता है क्योंकि यह ओपेक टोकन का संदर्भ देता है। –

+1

मैं किसी के कोड की प्रतिलिपि बनाने की बजाय तकनीक सीखना पसंद करूंगा – Ronit

9

वर्तमान में (v। 4.3.0 से, @ngular/common/http से नए HttpClient का उपयोग करते समय) कोणीय बॉक्स से प्रगति को सुनता है। तुम बस HttpRequest बनाने के लिए नीचे के रूप में वस्तु की जरूरत है:

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

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

और आप आप सदस्यता हर प्रगति घटना पर कहा कि मिल जाएगा का अनुरोध करने के लिए सदस्यता ले जब:

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

अधिक जानकारी here

संबंधित मुद्दे