Saltar al contenido

Obtener datos una vez con Observables en Angular 2

Posterior a de una extensa búsqueda de información hemos podido solucionar esta preocupación que tienen muchos de nuestros lectores. Te regalamos la solución y deseamos resultarte de mucha ayuda.

Solución:

1) Simplemente puede guardar los datos descargados en su servicio:

export class CustomersService 
  protected _customers: Array;

  constructor(public http: Http) 

  public getCustomers(): Observable> 
    return new Observable(observer => 
      if (this._customers) 
        observer.next(this._customers);
        return observer.complete();
      
      this.http
        .get(this.baseURI + this.url)
        .map((r: Response) => (r.json() as Array))
        .subscribe((customers: Array) => 
          this._customers = customers;
          observer.next(this.customers);
          observer.complete();
        );
    );
  

2) Toma de aproximación más corta refresh parámetro:

export class CustomersService 
  protected _customers: Array;

  constructor(public http: Http) 

  public getCustomers(refresh?: boolean): Observable> 
    if (!refresh && this._customers) 
      return Observable.of(this._customers);
    
    return this.http
            .get(this.baseURI + this.url)
            .map((c: Response) => (c.json() as Array))
            .do((customers: Array) => 
                this._customers = customers;
            );
    );
  
}

3) Aprovechando ReplaySubject:

export class CustomersService 
  protected _customers$: ReplaySubject> = new ReplaySubject(1);
  protected _customersInitialized: boolean;

  constructor(public http: Http) 

  public getCustomers(refresh?: boolean): Observable> 

Y luego:

this.customersService.getCustomers()
    .subscribe(customers => this.customers = customers);

También puede exponer el siempre actualizado customers campo de SomeService para fines de solo lectura (como mostrar en las plantillas) de esta manera:

public get customers(): ReadonlyArray 
  return this._customers;

Crearía un contenedor principal, buscaría los datos una vez y los pasaría a los componentes secundarios usando @Input.

Padre:

@Component(
    selector: 'BarFooHttpCaller',
    template: ´´
)

class BarFooHttpCaller 
    private data: any;
    constructor(private foobar:Foobar) 
        this.data = ;
    

    ngOnInit() 
        this.foobar.getCustomers().subscribe(() =>        
            console.log('httpdone') 
        );
        this.foobar.dataStream.subscribe((data) => 
            console.log('new data', data);
            this.data = data;
        )
    

Niño:

import  Component, Input  from '@angular/core';

@Component(
    selector: 'child',
    template: ´
data
´ ) export class Child @Input() data: any;

Si desea que varios niños se suscriban al mismo observable, pero solo ejecute el observable una vez, puede hacer lo siguiente.

Tenga en cuenta que esto se adhiere al diseño de observables ya que estamos ejecutando el observable en la capa de servicio (Observable.fromPromis(stream.toPromise()) cuando la ejecución debe realizarse desde la suscripción del componente. Ver https://www.bennadel. com/blog/3184-creating-leaky-abstractions-with-rxjs-in-angular-2-1-1.htm para obtener más información.

  //declare observable to listen to
  private dataObservable: Observable;

  getData(slug: string): Observable 

    //If observable does not exist/is not running create a new one
    if (!this.dataObservable) 

        let stream = this.http.get(slug + "/api/Endpoint")
            .map(this.extractData)
            .finally(() => 
                //Clear the observable now that it has been listened to
                this.staffDataObservable = null;
            );

        //Executes the http request immediately
        this.dataObservable = Observable.fromPromise(stream.toPromise());

            

    return this.staffDataObservable;
 

Si te ha resultado provechoso este artículo, sería de mucha ayuda si lo compartes con más entusiastas de la programación y nos ayudes a difundir nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *