Estoy definiendo servicio como clase, algo como esto:
@Injectable() export class MyService { ... }En otros componentes o páginas, estoy importando esa clase con solo el comando de importación.
import { MyService } from '../pages/services/myservice';En constructor:
constructor(public _MyService: MyService)En mi app.module.ts principal, he agregado ese servicio de clase como proveedor.
providers: [someOtherThings, MyService, someOtherThings]En Ionic 2, las cosas funcionan como se esperaba. El servicio es singleton.
Pero en Ionic 3, que usa angular 4, parece que cada componente está creando una nueva instancia de esa clase.
¿Hay alguna forma nueva de crear clases de servicios singleton en angular 4?
Estoy usando ionic 3 con lazyload y angular 4 y no tengo problemas. Para que sea único, asegúrese de que el módulo de su aplicación proporcione el servicio. y elimine los proveedores en @Component que usan el servicio.
Módulo de aplicación
@NgModule({ ... providers: [ StatusBar, SplashScreen, { provide: ErrorHandler, useClass: IonicErrorHandler }, Singleton // the service or provider to be single ton ] }) export class AppModule { }El servicio
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 el servicio en la página iónica
Primera página
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"); } }Segunda pagina
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 } }Tercera página : crea una nueva instancia si los proveedores agregaron el componente
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 } }asegúrese de eliminar los proveedores en el componente para que sea único.
Intente almacenar la instancia del Servicio en su AppModule y obtenga la instancia (en lugar de instanciarla) más tarde en otros componentes.
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; } }Y para recuperar el uso de la instancia del Servicio:
const myService = AppModule.injector.get(MyService);¡Consulta la documentación aquí !
En mi caso, tiene algo que ver con ReflectiveInjector .
Tengo dos servicios A y B, cada uno debe ser un servicio único que se refiera entre sí.
Si los inyecto en el constructor del otro, puede causar un error de compilación debido a la referencia circular.
si uso
const injector = ReflectiveInjector.resolveAndCreate([AService]); const a = injector.get(AService);en el constructor de B, creará otra instancia de A.
Y se debe resolver creando un CService que contenga los datos, y AService y BService pueden acceder a los datos a través de CService.