简体   繁体   English

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

[英]Data from Service cannot be accessed OnInit in Angular2

I created a WorkingData object that I use to pass certain data between components. 我创建了一个WorkingData对象,用于在组件之间传递某些数据。 One member of the object is today which is a Date object containing the current date. today ,该对象的一个​​成员是包含当前日期的Date对象。 I want to update this every second in a setInterval function, but the workingData object is undefined at this point giving me the console error: 我想在setInterval函数中每秒更新一次,但是workingData未定义workingData对象,这给了我控制台错误:

Cannot set property 'today' of undefined

app.component.ts 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();
  }
}

working-data.service.ts 工薪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);
  }
}

I'm confident the the service is valid because it generates the view using the workingData object and console.log s on a subsequent AfterContentChecked LifeCycle, but I cannot seem to use the object OnInit . 我确信该服务有效,因为该服务在随后的AfterContentChecked LifeCycle上使用workingData对象和console.log生成视图,但我似乎无法使用对象OnInit I suspect I'm not using a LifeCycle hook properly, but I don't understand how to implement it correctly. 我怀疑我没有正确使用LifeCycle挂钩,但是我不知道如何正确实现它。 How can I immediately begin the setInterval ? 我如何立即开始setInterval

You're trying to alter the data before it's resolved. 您正在尝试解决数据之前更改数据。 getWorkingData() is asynchronous function that's returning a promise, not the actual data. getWorkingData()是异步函数,它返回一个getWorkingData() ,而不是实际数据。 Try doing your updates when the data is actually available (in the callback). 当数据实际可用时(在回调中)尝试进行更新。

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

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

This is a use case for observables. 这是可观察对象的用例。 Both promises and observables serve the same purpose when an asynchronous operation should result in a single value. 当异步操作应产生单个值时,promise和Observable的目的相同。

For multiple values observables is better choice because it is their primary purpose. 对于多个值,可观察项是更好的选择,因为这是它们的主要目的。

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 result can be obtained with workingData结果可以通过

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

But in most scenarios it will be redundant, because workingData$ can be subscribed wherever needed, and observables can be bound in view with async pipe: 但是在大多数情况下,这将是多余的,因为可以在任何需要的地方订阅workingData$ ,并且可以使用async管道在视图中绑定可观察对象:

{{ workingData$ | async }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM