2016-11-14 42 views
0

我創建了一個WorkingData對象,我使用該對象在組件之間傳遞某些數據。該對象的一個​​成員是today這是包含當前日期的Date對象。我想在setInterval功能來更新這個每一秒,但workingData對象在這一點給我的控制檯錯誤是不確定的:Service的數據無法訪問Angular2的OnInit

Cannot set property 'today' of undefined 

app.component.ts

import { Component, OnInit, AfterContentChecked } from '@angular/core'; 
import { WorkingData } from './services/working-data/working-data'; 
import { WorkingDataService } from './services/working-data/working-data.service'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'], 
    providers: [ WorkingDataService ] 
}) 
export class AppComponent implements OnInit, AfterContentChecked { 

    workingData: WorkingData; 

    constructor(public _workingDataService: WorkingDataService) { } 

    getWorkingData() { 
    this._workingDataService.getWorkingData().then(workingData => this.workingData = workingData); 
    } 

    ngOnInit() { 
    this.getWorkingData(); 
    console.log('OnInit()'); 
    console.log(this.workingData);   // doesn't work 
    // setInterval(this.updateTime(), 1000); // doesn't work 
    } 
    ngAfterContentChecked() { 
    console.log('AfterContentChecked()'); 
    console.log(this.workingData);   // doesn't work the first call but does after it is called again at some later point 
    // setInterval(this.updateTime(), 1000); // doesn't work 
    } 
    updateTime() { 
     this.workingData.today = new Date(); 
    } 
} 

工作數據。 service.ts

import {Injectable} from '@angular/core'; 
import {WorkingData} from './working-data'; 
import {WORKINGDATA} from './mock-working-data'; 

@Injectable() 
export class WorkingDataService { 
    getWorkingData(): Promise<WorkingData> { 
    return Promise.resolve(WORKINGDATA); 
    } 
} 

我相信的服務是有效的,因爲它使用workingData對象和生成視圖s後續AfterContentChecked LifeCycle,但我似乎無法使用對象OnInit。我懷疑我沒有正確使用LifeCycle鉤子,但我不明白如何正確實施它。 我該如何立即開始setInterval

+1

爲什麼不在回調中設置'today'(並啓動更新間隔)?當您確實可以訪問'this.workingD ata'? – jonrsharpe

+1

'this._workingDataService.getWorkingData()'是異步的。你不能同時在'ngOnInit'中得到它的結果。你不應該。 *在setInterval函數*中每秒更新一次,可觀察是比承諾更好的選擇。 – estus

+0

請記住,您可以從一個時間間隔創建一個Observable並訂閱它。 'Observable.interval(1000)' – nicowernli

回答

2

這是一個observables的用例。當異步操作應該導致單個值時,promise和observables都有相同的用途。

對於多個值,observables是更好的選擇,因爲它是它們的主要用途。

import { Observable } from 'rxjs'; 
... 
export class AppComponent { 
    workingData$: Observable<WorkingData>; 

    constructor(public _workingDataService: WorkingDataService) { 
    this.workingData$ = Observable.interval(1000).startWith('initial value') 
    .concatMapTo(Observable.fromPromise(_workingDataService.getWorkingData())) 
    .do(data => data.today = new Date) 

} 

workingData結果可以與

this.workingData$.subscribe(data => this.workingData = data); 

來獲得,但在大多數情況下這將是多餘的,因爲workingData$可以任何需要的地方被訂閱,並且可觀察可以考慮與async管的約束:

{{ workingData$ | async }} 
2

您試圖在數據解決之前修改數據。 getWorkingData()是返回承諾的異步函數,而不是實際的數據。嘗試在數據實際可用時進行更新(在回調中)。

getWorkingData() { 
    return this._workingDataService.getWorkingData(); 
} 

ngOnInit() { 
    this.getWorkingData().then(workingData => { 
    this.workingData = workingData; 
    // do your magic here 
    }); 
... 
} 
+0

在ngOnInit中觀察結果似乎合乎邏輯後開始間隔 – Fiddles

+0

我同意這看起來也很合理,但我得到了同樣的錯誤。我知道該服務正在工作,因爲其他組件使用相同的服務在視圖中呈現其數據。 –

+0

您現在可以更新原始文章中的代碼,因此我們現在可以看到它的外觀? –