2017-04-20 92 views
2

我們想要做的是從一個url中調用一個端點,該端點返回兩個變量,這些變量可以在網站上的多個部分中使用。雖然我們正在使用http調用並訂閱它,但爲了加速網站,我們只需要調用一次api調用。爲了做到這一點,我們創建了一個服務的Observable。 Service在構造函數中調用Observable的值,但有時直接訪問鏈接時,將無法訂閱未定義的方法。這是使用微軟ADAL庫的例子代碼如下:設置角度爲2的可觀察變量

首先我們設置的變量作爲一個可觀察的服務:

@Injectable() 
export class MicrosoftGraphService { 
    public details: Observable<any>; 

然後我們在構造函數中設置觀察到的值:

constructor(
private _http:Http, 
private _adalService: AdalService, 
private _sanitizer:DomSanitizer 
) { 

this.getToken().subscribe(token => { 
    /** 
    * Get me data from graph to determine school_id and mis_id 
    */ 
    this.get('me', token, true).subscribe(me => { 
    this.details = new Observable(observer => { 
     observer.next({ 
      me: me 
     }); 
     observer.complete(); 
    }); 
    }); 
}); 

的爲gettoken函數是:

getToken(): Observable<any> { 
    return this._adalService 
     .acquireToken(this._adalService.config.endpoints.graph); 
} 

get函數是:那麼

get(endpoint, token, beta = false): Observable<any> { 
    return this._http.get(this._adalService.config.endpoints.graph + 
    this.getVersion(beta) + endpoint, { 
     headers: new Headers({ "Authorization": "Bearer " + token }) 
    }) 
    .map(res => { 
     return res.json(); 
    }); 
} 

這就是所謂的部件的構造函數如下:

this._microsoftGraph.details.subscribe(details => { 
    console.log(details); 
}); 

這應該添加的控制檯日誌我終端的返回,但是它在某些頁面上返回,並且它返回的其他頁面無法訂閱到未定義的頁面。 MicrosoftGraphService被調用並在兩個頁面上的構造函數中正確設置。

我想知道這是否因爲它的調用方式以及它的設置訪問基本url將調用父組件,因爲MicrosoftGraphService在該構造函數中被調用,所以它首先被初始化,所以在通過導航訪問第二個組件時可用。但是直接到子組件的URL位置可能意味着它在父代之前被首先調用,即使兩者都加載了MicrosoftGraphService。路由的

例如,如果它可以幫助:

const routes: Routes = [ 
{ 
    path: '', 
    component: SiteComponent, 
canActivate: [LoggedInGuard], 
children: [ 
    { path: 'dashboard', component: DashboardComponent }, 
    { path: 'tasks', component: TasksComponent }, 
    { 
     path: '', 
     redirectTo: '/dashboard' 
     , pathMatch: 'full' 
     // , terminal: true 
    } 
    ] 
}, 

回答

3

的問題是,你的public details: Observable<any>;在開始和你傳遞給getToken()認購未初始化把它設置爲一個新Observable每時間使用

this.details = new Observable(observer => { 
    observer.next({ 
     me: me 
    }); 
    observer.complete(); 
}); 

由於這個原因,你的組件會得到不同的對象,當他們訪問details,取決於對T他指出他們訪問它的時間。

我會建議做這樣的事情在你的服務如下:

detailsSubject = new Subject<any>(); 
public details = this.detailsSubject.asObservable(); 

// --- in your subscription where you set your Observable before 
this.detailsSubject.next(/* here comes your token */); 

欲瞭解更多信息,看看這個example