2016-11-14 3 views
0

Я создал объект WorkingData, который я использую для передачи определенных данных между компонентами. Один член объекта - today, который представляет собой объект Date, содержащий текущую дату. Я хочу, чтобы обновить это каждый второй в setInterval функции, но объект workingData не определен в данный момент дает мне ошибку консоли:Доступ к данным из службы невозможен OnInit in Angular2

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 объект и console.log с последующим AfterContentChecked LifeCycle, но я не могу использовать объект OnInit. Я подозреваю, что я не использую крючок LifeCycle правильно, но я не понимаю, как его правильно реализовать. Как я могу сразу начать setInterval?

+1

Почему вы не устанавливаете 'today' (и не начинаете интервал обновления) в обратном вызове, когда у вас определенно есть доступ к' this.workingD ata'? – jonrsharpe

+1

'this._workingDataService.getWorkingData()' является асинхронным. Вы не можете получить результат в 'ngOnInit' синхронно. и вы не должны. * обновлять каждую секунду в функции setInterval *, наблюдаемый - лучший выбор, чем обещание. – estus

+0

Помните, что вы можете создать Наблюдаемый с интервалом и подписаться на него. 'Observable.interval (1000)' – nicowernli

ответ

2

Это пример использования для наблюдаемых. Обе обещания и наблюдаемые функции служат той же цели, когда асинхронная операция должна приводить к одному значению.

Для нескольких значений наблюдаемые - лучший выбор, потому что это их основная цель.

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

Можете ли вы обновить код в исходном сообщении сейчас, чтобы мы могли видеть, как он выглядит на данный момент? –