来自Service的数据无法在Angular2中访问OnInit

时间:2016-11-14 22:17:06

标签: angular typescript lifecycle

我创建了一个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 LifeCycle上使用console.log对象和AfterContentChecked生成视图,但我似乎无法使用该对象OnInit。我怀疑我没有正确使用LifeCycle钩子,但我不明白如何正确实现它。 如何立即开始setInterval

2 个答案:

答案 0 :(得分:2)

您在解决之前尝试更改数据。 getWorkingData()是异步函数,它返回一个promise,而不是实际的数据。在数据实际可用时(在回调中)尝试进行更新。

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

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

答案 1 :(得分:2)

这是可观察的用例。当异步操作应该产生单个值时,promises和observable都有相同的用途。

对于多个值,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 }}