2017-02-11 2 views
1

Ich brauche Verwendung ng2-slim-loading-bar, um meinen Fortschritt zu zeigen, wenn Anfrage vom Back-End bekommen.ng2-slim-loading-bar für HTTP-Anfrage

Hier ist meine Komponente.

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

Diese Anfrage sollte 3-5 Sekunden von Anfrage zu lösen, so dass ich den Fortschrittsbalken zum Laden so machen muss. Das Problem hierbei ist, dass beim Laden der Seite nichts angezeigt wird, bis der Rückruf abgeschlossen ist. Nachdem ich alle meine Produkte gezeigt habe, wird es sofort verschwinden.

Irgendwas falsch hier? Bitte helfen Sie.

Antwort

0

Ich hatte das gleiche Problem in der Vergangenheit. Wenn Sie this._slimLoader.start(); verwenden, wird der Balken von 0% geladen und langsam erhöht. Dies bedeutet, dass Sie es nicht visuell starten können, da es sich am Rand des Browsers befindet.

Anstatt .start() zu verwenden, können Sie den Fortschritt auf einen bestimmten Prozentsatz festlegen, z. this._slimLoader.progress = 70; und dann .complete(); anrufen, sobald die Anfrage abgeschlossen ist.

Ich glaube YouTube verwendet diesen Stil.

0

Wie Todo's Antwort erwähnt, beginnt der Balken bei 0%. Sie müssen es auf 20% setzen und start() anrufen. Allerdings wird start() in einigen Intervallen nur schrittweise erhöht, und wenn es auf 100% trifft, verschwindet der Balken einfach und zeigt fälschlicherweise an, dass das Laden beendet ist. Es wäre nett, wenn start() einen Callback akzeptiert, der bei jedem Schritt aufgerufen wird, so dass Sie ihn bei 90% stoppen können. Aber das tut es nicht.

So, hier ist das, was ich in unserem Projekt haben (Red Hat Automatische Migration Toolkit):

  • In unserem HTTP-Service-Wrapper (Umgang mit OAuth), wir ein Ereignis ausgelöst,
  • , die dann durch gefangen unsere LoadingIndicatorService.
  • LoadingIndicatorService
    • hüllt den SlimLoaderBarService,
    • und verfolgt, wie viele HTTP-Anforderungen dort im Gange sind.
    • Dann zählt es den Prozentsatz und legt es auf eine Skala von 20 bis 90%.
    • Wenn alle HTTP-Anfragen abgeschlossen sind, bleibt es für etwa eine Sekunde bei 90% und wird dann complete() aufgerufen.

Wenn Sie mehrere Anfragen nach jedem Navigationsschritt haben, sieht das ganz natürlich und bietet eine gute UX. Wenn Sie normalerweise nur eine Anfrage haben, können Sie entweder die CSS-basierte Animation anpassen (länger machen) oder start() danach verwenden.

Hier sind einige der wichtigsten Codeteile:

@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-Service-Wrapper:

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

Für den kompletten Code, suchen github.com für Projekt Windup.

Verwandte Themen