Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

421
Vistas
¿Cómo creo un servicio singleton en Angular 2?

He leído que inyectar cuando el arranque debería hacer que todos los niños compartan la misma instancia, pero mis componentes principales y de encabezado (la aplicación principal incluye el componente de encabezado y la salida del enrutador) obtienen cada uno una instancia separada de mis servicios.

Tengo un FacebookService que uso para hacer llamadas a la API de JavaScript de Facebook y un UserService que usa FacebookService. Aquí está mi arranque:

 bootstrap(MainAppComponent, [ROUTER_PROVIDERS, UserService, FacebookService]);

Desde mi registro, parece que la llamada de arranque finaliza, luego veo que se crea FacebookService y luego UserService antes de que se ejecute el código en cada uno de los constructores, MainAppComponent, HeaderComponent y DefaultComponent:

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Actualizar (Angular 6 +)

La forma recomendada de crear un servicio singleton ha cambiado. Ahora se recomienda especificar en el decorador @Injectable en el servicio que debe proporcionarse en la 'raíz'. Esto tiene mucho sentido para mí y ya no es necesario enumerar todos los servicios proporcionados en sus módulos. Simplemente importa los servicios cuando los necesita y se registran en el lugar adecuado. También puede especificar un módulo para que solo se proporcione si se importa el módulo.

 @Injectable({ providedIn: 'root', }) export class ApiService { }
  • https://angular.io/guide/singleton-services
  • https://angular.io/guide/providers

Actualizar (Angular 2)

Con NgModule, creo que la forma de hacerlo ahora es crear un 'CoreModule' con su clase de servicio y enumerar el servicio en los proveedores del módulo. Luego, importa el módulo central en el módulo principal de su aplicación, que proporcionará una instancia a cualquier niño que solicite esa clase en sus constructores:

CoreModule.ts

 import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ApiService } from './api.service'; @NgModule({ imports: [ CommonModule ], exports: [ // components that we want to make available ], declarations: [ // components for use in THIS module ], providers: [ // singleton services ApiService, ] }) export class CoreModule { }

AppModule.ts

 import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { AppComponent } from './app.component'; import { CoreModule } from './core/core.module'; @NgModule({ declarations: [ AppComponent ], imports: [ CommonModule, CoreModule // will provide ApiService ], providers: [], bootstrap: [ AppComponent ] }) export class AppModule { }

Respuesta Original

Si enumera un proveedor en bootstrap() , no necesita enumerarlo en su decorador de componentes:

 import { ApiService } from '../core/api-service'; @Component({ selector: 'main-app', templateUrl: '/views/main-app.html', // DO NOT LIST PROVIDERS HERE IF THEY ARE IN bootstrap()! // (unless you want a new instance) //providers: [ApiService] }) export class MainAppComponent { constructor(private api: ApiService) {} }

De hecho, enumerar su clase en 'proveedores' crea una nueva instancia de la misma, si algún componente principal ya lo incluye, entonces los niños no necesitan hacerlo, y si lo hacen, obtendrán una nueva instancia.

over 4 years ago · Santiago Trujillo Denunciar

0

¡Jason tiene toda la razón! Es causado por la forma en que funciona la inyección de dependencia. Se basa en inyectores jerárquicos.

Hay varios inyectores dentro de una aplicación Angular2:

  • El root que configuras al arrancar tu aplicación
  • Un inyector por componente. Si usa un componente dentro de otro. El inyector de componentes es un elemento secundario del componente principal. El componente de la aplicación (el que especifica al impulsar su aplicación) tiene el inyector raíz como principal).

Cuando Angular2 intenta inyectar algo en el constructor del componente:

  • Mira en el inyector asociado con el componente. Si hay uno coincidente, lo usará para obtener la instancia correspondiente. Esta instancia se crea de forma perezosa y es un singleton para este inyector.
  • Si no hay ningún proveedor en este nivel, buscará en el inyector principal (y así sucesivamente).

Entonces, si desea tener un singleton para toda la aplicación, debe tener el proveedor definido a nivel del inyector raíz o del inyector del componente de la aplicación.

Pero Angular2 mirará el árbol del inyector desde abajo. Esto significa que se utilizará el proveedor del nivel más bajo y el alcance de la instancia asociada será este nivel.

Vea esta pregunta para más detalles:

  • ¿Cuál es la mejor manera de inyectar un servicio en otro en angular 2 (Beta)?
over 4 years ago · Santiago Trujillo Denunciar

0

Sé que angular tiene inyectores jerárquicos como dijo Thierry.

Pero tengo otra opción aquí en caso de que encuentre un caso de uso en el que realmente no quiera inyectarlo en el padre.

Podemos lograr eso creando una instancia del servicio, y al proporcionar siempre devolver eso.

 import { provide, Injectable } from '@angular/core'; import { Http } from '@angular/core'; //Dummy example of dependencies @Injectable() export class YourService { private static instance: YourService = null; // Return the instance of the service public static getInstance(http: Http): YourService { if (YourService.instance === null) { YourService.instance = new YourService(http); } return YourService.instance; } constructor(private http: Http) {} } export const YOUR_SERVICE_PROVIDER = [ provide(YourService, { deps: [Http], useFactory: (http: Http): YourService => { return YourService.getInstance(http); } }) ];

Y luego, en su componente, utiliza su método de suministro personalizado.

 @Component({ providers: [YOUR_SERVICE_PROVIDER] })

Y debería tener un servicio singleton sin depender de los inyectores jerárquicos.

No digo que esta sea una mejor manera, es solo en caso de que alguien tenga un problema donde los inyectores jerárquicos no son posibles.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda