简体   繁体   English

ionic2服务数据租借

[英]ionic2 service data rention

I have the following service class, its been set as singleton in providers etc. 我有以下服务类,它在提供程序等中被设置为单例。

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;
}

}

The console.log(this.appData) inside the subscribe outputs an object as it should the one after outputs undefined, shouldnt it be set by then? 订阅中的console.log(this.appData)输出一个对象,因为该对象应该在输出未定义的对象之后输出,是否应该在那时设置? to make the matters worse. 使事情变得更糟。

I am calling the loadappdata on constructor and in my pages i want to get the object by calling 我在构造函数上调用loadappdata,在我的页面中,我想通过调用来获取对象

export class HomePage {

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


}

but getAppData is always undefined, 但是getAppData始终是未定义的,

I am trying to have a service retain an object so my pages can get data from this as they need. 我试图让服务保留一个对象,以便我的页面可以根据需要从中获取数据。 I was under the impression that thats how one should utilize service to share data across pages 我给人的印象就是那应该如何利用服务来跨页面共享数据

You are facing those issues because of the asyncronous ajax request of the http.get call. 由于http.get调用的异步ajax请求,您遇到了这些问题。 The programm order in this.loadAppData function is as follows: First you do the ajax request this.http.get this.loadAppData函数中的编程顺序如下:首先,您执行ajax请求this.http.get

Next you console.log outside the subscribe 接下来您在订阅之外的console.log

Once the response of the get request receives the response the arrow function of subscribe will be called and you console.log again. 一旦get请求的响应收到响应,将调用subscription的箭头功能,然后再次console.log。

The solution is to return the http.get Observable from the service and subscribe to it in your component. 解决方案是从服务中返回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;
        });
    };
}

To cache your data you could return a Promise that resolves to locally cached data or if not available requests and returns. 要缓存数据,您可以返回一个Promise,该Promise解析为本地缓存的数据,或者如果没有可用的请求和返回,则返回该Promise。 For example: 例如:

@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);
                    });
            }
       });
}

1 - You can use ngrx store https://github.com/ngrx/store - to store the service results and each page will retrieve the information from the store. 1-您可以使用ngrx store https://github.com/ngrx/store-存储服务结果,并且每个页面都将从存储中检索信息。

2- Use ReplaySubject - 2-使用ReplaySubject-

In your service code: 在您的服务代码中:

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();
  }

In your home page: 在您的主页中:

export class HomePage {

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

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

} }

in Your Profile page: 在您的个人资料页面中:

export class ProfilePage {

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

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

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

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