私はこのようなサービスをクラスとして定義しています:
@Injectable()
export class MyService {
...
}
他のコンポーネントまたはページでは、importコマンドだけでそのクラスをインポートしています。
import { MyService } from '../pages/services/myservice';
コンストラクター内:
constructor(public _MyService: MyService)
メインのapp.module.tsで、そのクラスサービスをプロバイダーとして追加しました。
providers: [someOtherThings, MyService, someOtherThings]
Ionic 2、物事は期待通りに機能しています。サービスはシングルトンです。
ただし、Ionic 3では、angular 4を使用しています。すべてのコンポーネントがそのクラスの新しいインスタンスを作成しているようです。
angular 4?にシングルトンサービスクラスを作成する新しい方法はありますか?
Imを使用してionic 3 lazyloadとangular 4で問題がありません。シングルトンにするには、アプリモジュールがサービスを提供していることを確認します。サービスを使用する@Component。
アプリモジュール
@NgModule({
...
providers: [
StatusBar,
SplashScreen,
{ provide: ErrorHandler, useClass: IonicErrorHandler },
Singleton // the service or provider to be single ton
]
})
export class AppModule { }
サービス
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
@Injectable()
export class Singleton {
data = "init data";
constructor() {
console.log('Hello Singleton Provider');
}
set(data){
this.data = data;
}
log(){
console.log(this.data);
}
}
ionic pageのサービスのケース
最初のページ
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';
@IonicPage()
@Component({
selector: 'page-first',
templateUrl: 'first.html'
})
export class FirstPage {
constructor(public navCtrl: NavController, public navParams:
NavParams,private single:Singleton) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad First');
this.single.log(); // log init data;
this.single.set("First singleton data");
}
}
2ページ目
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';
@IonicPage()
@Component({
selector: 'page-second',
templateUrl: 'second.html'
})
export class SecondPage {
constructor(public navCtrl: NavController, public navParams:
NavParams,private single:Singleton) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad Second');
this.single.log(); // log First singleton data
}
}
ページ目プロバイダーがコンポーネントに追加された場合、新しいインスタンスを作成します
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';
@IonicPage()
@Component({
selector: 'page-second',
templateUrl: 'second.html',
providers:[Singleton] // wrong because its create a new instance
})
export class ThirdPage {
constructor(public navCtrl: NavController, public navParams:
NavParams,private single:Singleton) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad ThirdPage');
this.single.log(); // log init data
}
}
コンポーネントのプロバイダーを削除して、シングルトンにします。
サービスのインスタンスをAppModule
に保存して、インスタンスを取得します(インスタンス化する代わりに)後で他のコンポーネントで取得します。
import {Injector} from '@angular/core';
export class AppModule {
// Allows for retrieving singletons using 'AppModule.injector.get(MyService)' later in the code
static injector: Injector;
constructor(injector: Injector) {
AppModule.injector = injector;
}
}
また、サービスのインスタンスを取得するには、次を使用します。
const myService = AppModule.injector.get(MyService);
ドキュメントを確認してください ここ !
私の場合、ReflectiveInjector
と関係があります。
2つのサービスAとBがあり、それぞれが相互に参照するシングルトンサービスである必要があります。
他のコンストラクタにそれらを注入すると、循環参照のためにコンパイルエラーが発生する可能性があります。
私が使用する場合
const injector = ReflectiveInjector.resolveAndCreate([AService]);
const a = injector.get(AService);
bのコンストラクターで、Aの別のインスタンスを作成します。
また、データを保持するCServiceを作成することで解決する必要があり、AServiceとBServiceはCServiceを介してデータにアクセスできます。