2016-05-31 3 views
5

저는 angular2를 처음 접했고 뭔가가 붙어 있습니다.Angular2 전역 변수를 관찰 할 수 있습니다

나는 글로벌 settings.service를 만들었습니다. 이 서비스는 API에서 설정을 가져 와서 수집 된 데이터로 설정 모델을 채 웁니다.

서비스 :

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

이 잘 작동하고 나는 .MAP에서 반환 데이터를 테스트 할 때 설정이 올바르게 설정되어

하지만 내가 필요로하는 구성 요소에서 GetSettings를 호출 할 때 이 데이터는 비어있게됩니다. 서비스는 부트 스트랩에 정의됩니다.

'settings'변수를 관찰 가능하게 설정해야합니까? 어떤 도움을 주시면 감사하겠습니다!

Tnx!

+0

실제 코드가 다른 것 같습니다. '.map에서 반환 데이터를 테스트 할 때 올바르게 설정됩니다. ' 이 코드는'this.http.get ('/ settings') .map (응답 => { this.settings = response.json() });''subscribe (...)없이 실행되지 않는다 ' –

+0

예, 실제 코드는 다릅니다;)하지만 질문을 위해 코드를 단순화했습니다. 코드 예제를 업데이트하겠다.) – Jeffrey

답변

2

나는 do 연산자를 사용하여 서비스에 캐싱을 구현하는 것이 :이 같은 서비스를 사용하는 이유하지

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

BehaviorSubject를 사용하면 '공유()'또는 캐시 할 필요가 없다. 관심이 있다면 내 대답을보십시오. –

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

하고 싶어 어디 .subscribe() 방법을 사용하는 것보다

해당 데이터와보기에 표시

+0

나는 그것을 좋아하지만 API 호출 양을 줄이려고합니다. 데이터는 결코 변경되지 않거나 클라이언트 자체에 의해서만 변경되므로 매번 '새로운'데이터를 호출 할 필요가 없습니다. – Jeffrey

+0

@thierry가'observable'을 사용하여 @thierry로 사용할 수있는 것보다 괜찮습니다. –

7

귀하의 서비스에서 BehaviorSubject를 사용하십시오. 그것은 이미 공유하고, 새로운 가입자에게 현재의 값을 줄 것이다 (그래서 당신을 위해 캐싱을 수행) :

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

그런 다음 asyncPipe하여 템플릿의 관찰을 사용하거나으로 데이터를 추출 구성 요소 변수 : 나는 4 초 후, 01 대기 자식 요소를 가지고있는 Plunker에서

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

Plunker

s는 최신/현재 값이 실제로 검색되었음을 나타냅니다. Plunker는 또한 asyncPipe의 사용법을 보여줍니다.

+0

전역 데이터에 BehaviorSubject를 사용하는 아이디어가 마음에 들지만 실제 데이터를 가져 오기 전에 방출되는 초기 값을 다루는 데 어려움이 있습니다. . 필자의 경우, BehaviorSubject의 값을 기반으로 한 구성 요소에 추가 데이터를 가져와야하는데, null 값이 있으면 실패합니다. 어떤 아이디어가 이것을 해결하는 방법? – Liquinaut

+0

내 문제가 해결되었습니다. 솔루션을 찾는 사람은 BehaviorSubject 대신 ReplaySubject를 사용하여 초기 값없이 변경 사항을 방출하는 Subject를 얻을 수 있습니다. ReplaySubject는 next()가 처음 호출 될 때까지 데이터를 방출하지 않습니다. – Liquinaut

+0

@ Mark Rajcok - 왜 4 초를 기다리지? 그의 초기 값을 기다리는 방법? –

관련 문제