2016-07-01 20 views
9

Quello che sto cercando di fare è:
Voglio usare lo spinner ogni volta che una richiesta http si avvicina. In altre parole, voglio che l'utente visualizzi una schermata di caricamento ogni volta che si verifica una richiesta http nel mio app.component.
I miei file spinner.component e spinner-service sono gli stessi della risposta nella domanda this.
E componente del mio app.component èCaricatore angolare 2 su ogni richiesta http

@Component({ 
    selector: 'todoApi', 
    template: ` 
     <div class="foo"> 
      <spinner-component></spinner-component> 
      <h1>Internship Project</h1> 
      <a [routerLink]="['Dashboard']">Dashboard</a> 
      <a [routerLink]="['Tasks']">List</a> 
      <router-outlet></router-outlet> 
     <div> 
    `, 
    directives: [ROUTER_DIRECTIVES,SpinnerComponent], 
    providers: [ 
     ROUTER_PROVIDERS, 
    ] 
}) 

@RouteConfig([ 
    { 
     path: '/dashboard', 
     name: 'Dashboard', 
     component: DashboardComponent, 
     useAsDefault: true 
    },{ 
     path: '/tasks', 
     name: 'Tasks', 
     component: TaskComponent 
    },{ 
     path: '/detail/:id', 
     name: 'TaskDetail', 
     component: TaskDetailComponent 
    }, 
]) 

Per conclue, ogni volta che si verifica una richiesta HTTP in uno di questi percorsi, voglio mostrare la casella di selezione per utente. So che questa è stata una brutta domanda, ma io sono nuovo di Angular 2 e sarei davvero grato se qualcuno potesse aiutarmi con quello.
Grazie mille!
Modifica !:
Soluzione con la risposta di Günther: Ho avvolto la mia http e spinner-service in un componente HttpClient e lo ha usato al posto del normale modulo HTTP. Qui è la mia HttpClient componente:

import { Injectable } from '@angular/core'; 
import { Http, Headers } from '@angular/http'; 
import { SpinnerService} from './spinner-service'; 

@Injectable() 
export class HttpClient { 
    constructor(
     private http: Http, 
     public spinner: SpinnerService 
    ){ 

    } 

    createAuthorizationHeader(headers:Headers) { 
    headers.append('Authorization', 'Basic ' + btoa('username:password')); 
    } 

    get(url) { 
    this.spinner.start(); 
    let headers = new Headers(); 
    this.createAuthorizationHeader(headers); 
    return this.http.get(url, { headers: headers }).do(data=> {this.spinner.stop()}); 
    } 

    post(url, data) { 
    this.spinner.start(); 
    let headers = new Headers(); 
    this.createAuthorizationHeader(headers); 
    return this.http.post(url, data, { headers: headers }).do(data=> {this.spinner.stop()}); 
    } 
} 
+0

Forse si crea un servizio personalizzato per eseguire le richieste http estendono la HttpClass fornito dal angolare e tenere traccia dello stato 'isBusy' nel vostro servizio personalizzato su ogni richiesta – Lekhnath

risposta

6

utilizzare un servizio che viene condiviso tra Http (ci sono risposte già che ne dite di confezionamento Http nella tua classe) e il <spinner-component>. Vedere anche https://angular.io/docs/ts/latest/cookbook/component-communication.html

Nel servizio condiviso mantenere un contatore di avviato (aumento) e completato/fallito richieste HTTP e ne informa il <spinner-component> ogni volta quando il contatore passa da 0 a >0 o da >0 a 0 per abilitare o disabilitare per sé .

+0

Questa è stata una risposta molto utile per me Günter! Molte grazie! Farò del mio meglio e vedrò se il wrapping di Http risolverà il problema o no. – ozata

+0

Grazie ancora Günter! – ozata

+0

Si prega di creare un esempio? – gtzinos

1

Solo per la gente che arriva qui da ora in poi ...

Con questa soluzione il filatore non si fermerà in caso di errore con la richiesta HTTP. Assicurati di effettuare le seguenti operazioni:

... 
return this.http.post(url, data, { headers: headers }) 
    .do(data=> {this.spinner.stop()}, 
    err=> {this.spinner.stop()); 
... 
3

Grazie per la risposta Günter Zöchbauer di, un esempio che ho costruito in base alle mie esigenze. Non ho usato un wrapper HTTP che sarebbe stato più facile da usare, tuttavia, questo esempio funziona con più chiamate di servizi basate sul tuo suggerimento contatore. Spero che aiuti qualcuno :)

  1. Creare il servizio Caricatore.

    import { Injectable } from '@angular/core'; 
    import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 
    
    @Injectable() 
    
    export class LoaderService { 
        public loaderCounter: BehaviorSubject<number> = new BehaviorSubject<number>(0); 
        displayLoader(value: boolean) { 
         let counter = value ? this.loaderCounter.value + 1 : this.loaderCounter.value - 1; 
         this.loaderCounter.next(counter); 
        } 
    } 
    
  2. includere il servizio entro i fornitori di tuo maain file del modulo (Es: AppModule)

  3. nel file componente principale (Es: AppComponent), iscriviti ai modifiche e riflettono al loader (nel mio caso è un componente separato ).

    //Imports 
    import { Subscription } from 'rxjs/Subscription'; 
    import { LoaderService } from './core/loader.service'; 
    .. 
    @Component({ 
        selector: 'my-app', 
        template: ` 
        <div class="container-fluid content"> 
         <router-outlet></router-outlet> 
        </div> 
        <spinner [visible]="displayLoader"></spinner> 
        ` 
    }) 
    
    export class AppComponent implements OnInit, OnDestroy { 
        displayLoader: boolean; 
        loaderSubscription: Subscription; 
        constructor(private loaderService: LoaderService) {} 
    
        ngOnInit() { 
         this.loaderSubscription = this.loaderService.loaderCounter.subscribe((counter: number) => { 
          this.displayLoader = counter != 0; 
         }); 
        } 
    
        ngOnDestroy() { 
         this.loaderSubscription.unsubscribe(); 
        } 
    } 
    
  4. Utilizzando il servizio loader:

    import { LoaderService } from './core/loader.service'; 
        .. 
        export class SampleComponent implements OnInit { 
         constructor(private _service: SomeService, private loader: LoaderService) { } 
    
        ngOnInit() { 
         this.loader.displayLoader(true); 
         this._service.getBalance().subscribe(
          response => ..do something.., 
          () => .. error.., 
          () => this.loader.displayLoader(false) 
         ); 
        } 
    } 
    
+0

Molto bello ... ma perché la tua chiamata ajax all'interno del componente? Penso che dovresti chiamare il metodo di servizio del caricatore all'interno di un altro servizio dove viene effettuata la chiamata ajax, no? – MadCatm2

+0

Dalla mia conoscenza di Angular 2, si dispone di un servizio, e si chiama e si collega a livello di componente semplicemente ai valori che si hanno. Non sono del tutto sicuro del motivo per cui avresti bisogno di più servizi poiché hai ancora bisogno di legare la risposta con il modello/le variabili all'interno del componente. –

Problemi correlati