2017-01-23 3 views
0

я следующий класс обслуживания, его были установлены как синглтон в поставщиках и т.д.ionic2 rention данных службы

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { Geolocation } from 'ionic-native'; 
import { Platform } from 'ionic-angular'; 

import 'rxjs/Rx'; 

@Injectable() 
export class TestService { 
private appData: any; 
constructor(private http: Http) { 
    console.log("service constructor called"); 
    this.loadAppData(); 
} 

loadAppData() { 
    let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
    this.http.get(url).map(res => res.json()).subscribe(data => { 
     this.appData = data; 
     console.log(this.appData); 
    }); 
    console.log(this.appData); 
} 
getAppData() 
{ 
    return this.appData; 
} 

} 

console.log (this.appData) внутри подписываются выходов объект, как он должен один после выходов undefined, не должен ли он быть установлен к тому времени? чтобы усугубить ситуацию.

Я звоню loadappdata на конструктор и в моих страницах я хочу, чтобы получить объект, вызвав

export class HomePage { 

constructor(public navCtrl: NavController, public testService: TestService) { 
console.log(testService.getAppData()); 
}; 


} 

но getAppData всегда неопределенная,

Я пытаюсь получить услугу сохранить объект поэтому мои страницы могут получать данные из этого по мере необходимости. У меня сложилось впечатление, что это то, как следует использовать услугу для обмена данными по страницам

ответ

0

Вы столкнулись с этими проблемами из-за асинхронного запроса ajax вызова http.get. Порядок программки в this.loadAppData функции выглядит следующим образом: Сначала вы делаете запрос Ajax this.http.get

Далее вы console.log вне подписаться

После того, как ответ запроса GET получает ответ будет вызываться функция стрелки subscribe, и вы снова будете console.log.

Решение состоит в том, чтобы вернуть http.get Observable из службы и подписаться на него в вашем компоненте.

@Injectable() 
export class TestService { 
constructor(private http: Http) {} 

loadAppData() { 
    let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
    return this.http.get(url).map(res => res.json()); 
} 


export class HomePage { 
    constructor(public navCtrl: NavController, public testService: TestService) { 
     this.testService.loadAppData().subscribe(data => { 
      this.appData = data; 
     }); 
    }; 
} 

Для кэширования данных вы можете вернуть Promise, который разрешает локально кэшированные данные или если недоступные запросы и возвраты. Например:

@Injectable() 
export class TestService { 

    public data: any; 

    constructor(private http: Http) {} 

    loadAppData() { 

     return new Promise((resolve) => { 
      if (this.data) { 
       return resolve(this.data); 
      } else { 
       let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
       return this.http.get(url) 
        .map(res => res.json()) 
        .subscribe(data => { 
         this.data = data; 
         return resolve(data); 
        }); 
      } 
     }); 
} 
+0

, но если я сделаю несколько вызовов для загрузкиAppData из нескольких страниц, которые будут вызывать URL-адрес несколько раз? Я пытаюсь вызвать loadAppData один раз и получить результат, который будет использоваться без необходимости повторного вызова службы – Zoinky

+0

Я добавил код. Недостатком является то, что у вас нет контроля над повторной загрузкой данных. Вместо этого вы можете использовать ваш app.component, чтобы загрузить данные, как вы это делаете в HomePage моего первого примера, а в функции успеха подписки назначьте данные переменной-члену TestService, к которой вы обращаетесь на каждой странице, а затем назначьте rootPage. – LuJaks

0

1 - Вы можете использовать ngrx магазин https://github.com/ngrx/store - для хранения результатов обслуживания и каждая страница будет извлекать информацию из хранилища.

2- Использование ReplaySubject -

В коде службы:

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { Geolocation } from 'ionic-native'; 
import { Platform } from 'ionic-angular'; 

import 'rxjs/Rx'; 

@Injectable() 
export class TestService { 
private appData: any; 
constructor(private http: Http) { 
    this.userSubject = new ReplaySubject<any>(1); 
this.loadAppData().subscribe(resp => {console.log(resp)}); 
} 

loadAppData():observable<any> { 
    let url = `/api/b502daab-2c7b-4cea-a00e-dc5aa6b58196`; 
    this.http.get(url).map(res => res.json()).map(data => { 
     this.userSubject.next(data); 
     return data; 
    }); 
    console.log(this.appData); 
} 

get appData(): Observable<any> { 
    return this.userSubject.asObservable(); 
    } 

В вашей домашней странице:

export class HomePage { 

constructor(public navCtrl: NavController, public testService: TestService) { 
console.log(testService.getAppData()); 
}; 

ngOninit() { 
this.appData.subscribe(resp => { 
console.log(resp) 
}); 

}

на странице профиля:

export class ProfilePage { 

    constructor(public navCtrl: NavController, public testService: TestService) { 
    console.log(testService.getAppData()); 
    }; 

    ngOninit() { 
    this.appData.subscribe(resp => { 
    console.log(resp) 
    }); 
} 
+0

Не могу я просто сохранить объект, я вернусь в глобальном масштабе, чем нужно использовать магазин? кажется, неэффективно хранить и извлекать моменты позже. – Zoinky

Смежные вопросы