2016-05-31 28 views
5

Ben açısal2 oldukça yeni ve ben bir şey üzerinde sıkışmış durumdayım.Angular2 global değişken gözlemlenebilir

Ben küresel settings.service oluşturduk. Bu hizmet, bir API'dan ayarları alır ve ayarlar modelini toplanan verilerle doldurur.

hizmeti:

public settings : settingsModel; 

constructor(public http: Http){ 
    this.setSettings() 
     .subscribe(
      (data) => { 
        this.settings = data 
      }); 
    } 

setSettings() : Observable<any>{ 
    return : this.http.get('/settings') 
      .map(response => response.json()); 
} 

getSettings(){ 
    return this.settings; 
} 

Bu iyi çalışır ve ben .map dönüş verilerini test ederken ayarlarının düzgün

Ama gerek bileşeninden GetSettings aramaya çalıştığınızda Bu veriler boş döner. Servis önyüklemede tanımlanmıştır.

Ben 'setting' değişken gözlemlenebilir yapmak gerekiyor mu? Herhangi bir yardım çok takdir edilecektir!

Tnx!

+0

Gerçek kodunuz farklı görünüyor. '.map'de dönüş verilerini test ettiğimde doğru ayarlanmış. Bu kod 'this.http.get ('/ settings') .map (response => { this.settings = response.json() });' asla abone olmadan çalıştırılamaz (...) ' –

+0

Evet, asıl kodum farklı;) Ama soru için kodu basitleştirdim. Kod örneğini güncelleyeceğim;) – Jeffrey

cevap

2

Ben do operatörü kullanarak hizmetine önbelleğe alma uygulamak olacaktır: Eğer böyle hizmetinizi kullanan neden olmasın

private settings : settingsModel; 

constructor(public http: Http){ 
    this.settingsObservable = this.http.get('/settings') 
     .map(response => response.json()) 
     .do(settings => { 
      this.settings = settings; 
     }).share(); 
} 

getSettings() { 
    if (this.settings) { 
    return Observable.of(this.settings); 
    } else { 
    return this.settingsObservable; 
    } 
} 
+1

Bir BehaviorSubject kullanırsanız, 'paylaşmak()' veya önbelleğe sahip olmanız gerekmez. İlgilenirse cevabımı görün. –

0

: -

public settings : settingsModel; 

constructor(public http: Http){ } 

GetSettings(){ 
    return this.http.get('/settings') 
    .map(response => { 
      this.settings = response.json() // here setting your data to `this.setting` 
      return this.settings; 
     }) 
     .catch(err => { 
      console.log(err) // handle your error as you want to handle 
     }) 
} 

ve almak istediğiniz .subscribe() yöntemi kullanmak daha

görünümünde

+0

Bunu öyle yaptım, ancak API çağrılarının miktarını azaltmaya çalışıyorum. Veriler hiçbir zaman değişmediğinden veya yalnızca müşterinin kendisi tarafından değiştirildiğinden, her seferinde 'yeni' veriyi aramaya gerek yoktur. Eğer @thierry olarak kullanabileceğiniz daha iyi – Jeffrey

+0

'kullanarak onun cevabını önerdi observable' –

7

kullanın hizmetinizde bir BehaviorSubject veri ve gösteri. Zaten paylaşılır ve yeni abonelerine akım değeri verecektir (bu yüzden sizin için önbelleğe alma yapar):

import {Injectable}  from '@angular/core'; 
import {Http}   from '@angular/http'; 
import {BehaviorSubject} from 'rxjs/BehaviorSubject'; 
import {settingsModel} from 'settingsModel'; 

@Injectable() 
export class MyService { 
    private _settingsSource = new BehaviorSubject<settingsModel>(null); 
    settings$ = this._settingsSource.asObservable(); 
    constructor(private _http:Http) { 
    this._http.get('./settings.json') 
     .subscribe(response => { 
     //console.log('response', response) 
     this._settingsSource.next(response.json()) 
     }); 
    } 
} 

Ardından asyncPipe ile şablonunda gözlemlenebilir kullanabilir veya bir veri ayıklamak bileşen değişken: Ben 4 saniye sonra 01 bekler bir çocuk bileşeni var Plunker yılında

this.settings$ = this._myService.settings$; // use with asyncPipe 
this._myService.settings$.subscribe(data => this.settings = data); 

Plunker

En güncel/güncel değerin gerçekten alındığını göstermek içins. Plunker ayrıca asyncPipe kullanımını gösterir.

+0

Küresel veriler için bir BehaviorSubject kullanarak fikir gibi, ben herhangi bir gerçek veri alınamadı olmuştur öncesi yayılan başlangıç ​​değerinin uğraşan zorluklar . Benim durumumda, null bir değer içeriyorsa başarısız olan, BehaviorSubject öğesinin değerine bağlı olarak bir bileşendeki ek verileri almam gerekir. Bunun nasıl çözüleceğine dair bir fikrin var mı? – Liquinaut

+0

Sorunumu çözdüm. Çözüm arayan herkes için, bir başlangıç ​​değerine sahip olmadan değişiklik yayan bir Konu almak için bir DavranışSubject yerine bir ReplaySubject kullanabilirsiniz. ReplaySubject, bir sonraki() ilk kez çağrılana kadar herhangi bir veri yaymayacaktır. – Liquinaut

+0

@Mark Rajcok - neden 4 saniye beklersiniz? İlk değeri için nasıl beklemeli? –

İlgili konular