Cómo compartir el servicio entre dos módulos - @NgModule en angular no entre a los componentes?
En mi aplicación, tengo dos módulos bootstrap diferentes (@NgModule
) que se ejecutan de forma independiente en una aplicación. No hay un módulo de bootstrap separado de bit angular app y ahora quiero que se comuniquen entre sí y compartan datos.
Sé a través del servicio @Injectable
como proveedor en el módulo, puedo compartir datos en todos los componentes bajo @NgModule
pero cómo compartiré datos entre dos módulos diferentes ( no componente dentro del módulo ).
¿Hay alguna forma en que un objeto de servicio puede se puede acceder en otro módulo? ¿Hay alguna forma de acceder al objeto de Servicio disponible en la memoria del navegador y usarlo en mi otro módulo angular?
5 answers
Puede crear una instancia de un servicio fuera de Angular y proporcionar un valor:
class SharedService {
...
}
window.sharedService = new SharedService();
@NgModule({
providers: [{provide: SharedService, useValue: window.sharedService}],
...
})
class AppModule1 {}
@NgModule({
providers: [{provide: SharedService, useValue: window.sharedService}],
...
})
class AppModule2 {}
Si una aplicación cambia el estado en SharedService
o llama a un método que hace que un Observable
emita un valor y el suscriptor está en una aplicación diferente al emisor, el código en el suscriptor se ejecuta en el NgZone
del emisor.
Por lo tanto, cuando se suscriba a un observable en SharedService
use
class MyComponent {
constructor(private zone:NgZone, private sharedService:SharedService) {
sharedService.someObservable.subscribe(data => this.zone.run(() => {
// event handler code here
}));
}
}
Véase también Cómo crear modales de bootstrap dinámicamente como Angular2 componentes?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:38
Según la versión final de Angular 2, los servicios proporcionados por un módulo están disponibles para todos los demás módulos que lo importan.
La Guía Oficial de Estilo aconseja que los servicios de toda la aplicación (singletons) que se van a reutilizar en cualquier lugar de la aplicación deben ser proporcionados por algunos Core Module
, que se van a importar en el principal App Module
para que sea inyectable en todas partes.
Si no utiliza una estructura que implique un módulo Core con singletons compartidos, y está desarrollar independientemente dos NgModules, y desea que un servicio en uno de ellos se utilice en el otro, entonces la única solución es importar el proveedor en el otro :
Aquí está el módulo proveedor:
/// some.module.ts
import { NgModule } from '@angular/core';
import { SomeComponent } from './some.component';
@NgModule({
imports: [],
exports: [],
declarations: [SomeComponent],
providers: [ MyService ], // <======================= PROVIDE THE SERVICE
})
export class SomeModule { }
Aquí está el otro módulo, que quiere usar MyService
/// some-other.module.ts
import { NgModule } from '@angular/core';
import { SomeModule } from 'path/to/some.module'; // <=== IMPORT THE JSMODULE
import { SomeOtherComponent } from './some.other.component';
@NgModule({
imports: [ SomeModule ], // <======================== IMPORT THE NG MODULE
exports: [],
declarations: [SomeOtherComponent],
providers: [],
})
export class SomeOtherModule { }
De esta manera, el servicio debe ser inyectable en cualquier componente SomeOtherModule
declara, y en SomeModule sí mismo-apenas lo pide en el constructor:
/// some-other.module.ts
import { MyService } from 'path/to/some.module/my-service';
/* ...
rest of the module
*/
export class SomeOtherModule {
constructor( private _myService: MyService) { <====== INJECT THE SERVICE
this._myService.dosmth();
}
}
Si esto no responde a su pregunta, yo te invito a reformularlo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-15 08:32:36
-
Crear módulo compartido
@NgModule({}) export class SharedModule { static forRoot(): ModuleWithProviders { return { ngModule: SharedModule, providers: [SingletonService] }; } }
-
En el módulo de la aplicación son su módulo de aplicación principal importar el módulo compartido como ese
SharedModule.forRoot()
-
Cualquiera de los módulos secundarios si necesita importar el módulo compartido, impórtelo sin la raíz para
SharedModule
Https://angular-2-training-book.rangle.io/handout/modules/shared-modules-di.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-15 11:36:19
La respuesta que Günter Zöchbauer dio es genial, sin embargo, un problema que puede tener es que
window.sharedService
Causará un error en TypeScript. Puede evitar esto reemplazando todas las instancias de
window.sharedService
Con
(<any>window).sharedService
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-20 16:45:04
Intenté usar las ideas en esta respuesta para compartir datos entre múltiples módulos bootstrapeados en mi aplicación angular. Los datos que me interesaban provenían de un http.get () call. Fue una llamada cara y yo quería solamente hacer la llamada una vez y compartir sus resultados entre mis 2 bootstrap módulos.
Inicialmente, almacené el servicio como una propiedad en mi objeto global window como se sugirió, pero al final, decidí usar variables estáticas y llamar a publishReplay () en mi observable para crear un Replaysujeto para reproducir mis emisiones a futuros suscriptores. Esto permitió que varios suscriptores compartieran datos y solo hicieran la llamada REST una vez.
Una advertencia aquí... La pregunta original preguntaba cómo compartir un servicio... Esta respuesta no comparte un servicio... Se crean varios servicios, pero los datos se comparten a medida que el observable se almacena en una variable estática... Eso significa que el observable permanece mientras su aplicación y debido a la llamada a publishReplay()
cualquiera que se suscriba a los observables reproduce los datos previamente devueltos.
Aquí está mi código:
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs/Rx';
import { Http } from '@angular/http';
@Injectable()
export class InitService {
static observable: Observable<number> = null;
constructor(private http: Http) {}
getInitData(): Observable<number> {
if (InitService.observable == null) {
InitService.observable = this.http.get('api/Init')
.map(this.extractData)
.publishReplay()
.refCount()
.catch(this.handleError);
}
return InitService.observable;
}
extractData(res: Response) {
let body: any = res.json();
return body || {};
}
}
Espero que esto ayude.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-11 21:00:23