web-dev-qa-db-fra.com

Singletons en Ionic 3, Angular 4

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?

24
Dragan Malinovic

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.

24
Ade Novan

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 !

2
SrAxi

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.

1
Ovilia