Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

428
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!