Angular2 中的 OnInit 无法访问来自服务的数据
Data from Service cannot be accessed OnInit in Angular2
我创建了一个 WorkingData
对象,用于在组件之间传递某些数据。该对象的一个成员是 today
,它是一个包含当前日期的 Date
对象。我想在 setInterval
函数中每秒更新一次,但此时 workingData
对象未定义,给我控制台错误:
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();
}
}
工作-data.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
对象和 console.log
s 在随后的 AfterContentChecked
生命周期中生成视图,但我似乎无法使用对象 OnInit
。我怀疑我没有正确使用 LifeCycle 挂钩,但我不明白如何正确实现它。 如何才能立即开始 setInterval
?
您正试图在数据解析之前更改数据。 getWorkingData()
是返回承诺而非实际数据的异步函数。尝试在数据实际可用时(在回调中)进行更新。
getWorkingData() {
return this._workingDataService.getWorkingData();
}
ngOnInit() {
this.getWorkingData().then(workingData => {
this.workingData = workingData;
// do your magic here
});
...
}
这是可观察对象的用例。当异步操作应该产生单个值时,promises 和 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$
可以在任何需要的地方订阅,并且 observables 可以用 async
管道绑定到视图中:
{{ workingData$ | async }}
我创建了一个 WorkingData
对象,用于在组件之间传递某些数据。该对象的一个成员是 today
,它是一个包含当前日期的 Date
对象。我想在 setInterval
函数中每秒更新一次,但此时 workingData
对象未定义,给我控制台错误:
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();
}
}
工作-data.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
对象和 console.log
s 在随后的 AfterContentChecked
生命周期中生成视图,但我似乎无法使用对象 OnInit
。我怀疑我没有正确使用 LifeCycle 挂钩,但我不明白如何正确实现它。 如何才能立即开始 setInterval
?
您正试图在数据解析之前更改数据。 getWorkingData()
是返回承诺而非实际数据的异步函数。尝试在数据实际可用时(在回调中)进行更新。
getWorkingData() {
return this._workingDataService.getWorkingData();
}
ngOnInit() {
this.getWorkingData().then(workingData => {
this.workingData = workingData;
// do your magic here
});
...
}
这是可观察对象的用例。当异步操作应该产生单个值时,promises 和 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$
可以在任何需要的地方订阅,并且 observables 可以用 async
管道绑定到视图中:
{{ workingData$ | async }}