Je définis le service comme une classe, quelque chose comme ceci:
@Injectable()
export class MyService {
...
}
Dans d'autres composants ou pages, j'importe cette classe avec juste la commande d'importation.
import { MyService } from '../pages/services/myservice';
En constructeur:
constructor(public _MyService: MyService)
Dans mon app.module.ts principal, j'ai ajouté ce service de classe en tant que fournisseur.
providers: [someOtherThings, MyService, someOtherThings]
Dans Ionic 2, les choses fonctionnent comme prévu. Le service est singleton.
Mais dans Ionic 3, qui utilise angular 4, il semble que chaque composant crée une nouvelle instance de cette classe).
Existe-t-il une nouvelle façon de créer des classes de services singleton dans angular 4?
J'utilise ionic 3 avec lazyload an angular 4 et ne pas avoir les problèmes. Pour le rendre singleton, assurez-vous que votre module d'application fournit le service. Et supprimez les fournisseurs sur @Composant qui utilise le service.
Module d'application
@NgModule({
...
providers: [
StatusBar,
SplashScreen,
{ provide: ErrorHandler, useClass: IonicErrorHandler },
Singleton // the service or provider to be single ton
]
})
export class AppModule { }
Le service
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);
}
}
Tes Case le service sur ionic
Première 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");
}
}
Deuxième page
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
}
}
Troisième page il crée une nouvelle instance si des fournisseurs sont ajoutés sur le composant
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
}
}
assurez-vous de supprimer les fournisseurs sur le composant pour le rendre singleton.
Essayez de stocker l'instance du Service dans votre AppModule
et récupérez l'instance (au lieu de l'instancier) plus tard dans d'autres composants.
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;
}
}
Et pour récupérer l'utilisation de l'instance du service:
const myService = AppModule.injector.get(MyService);
Consultez la documentation ici !
Dans mon cas, cela a quelque chose à voir avec ReflectiveInjector
.
J'ai deux services A et B, chacun devrait être un service unique se référant l'un à l'autre.
Si je les injecte dans le constructeur de l'autre, cela peut provoquer une erreur de compilation, en raison d'une référence circulaire.
Si j'utilise
const injector = ReflectiveInjector.resolveAndCreate([AService]);
const a = injector.get(AService);
dans le constructeur de B, cela fera une autre instance de A.
Et cela devrait être résolu en créant un CService contenant les données, et AService et BService peuvent accéder aux données via CService.