Búsqueda de sitios web

javascript - Angular 5 - Cómo consumir la clave de un proveedor declarada usando InjectionToken en un componente


Estoy aprendiendo varios métodos sobre cómo podemos implementar Dependency Injection en Angular 5. Se sabe que Angular 5 tiene 3 métodos diferentes de cómo podemos declarar la clave/token del proveedor al declarar una dependencia.

Primero, usando Clase (la forma más fácil y común), por ejemplo:

// in app.module.ts
import { HotMail } from './hot-mail';
...
...
...
@NgModule({
  providers: [
    {
      provide: HotMail,
      useClass: HotMail
    }
  ],
})
...
...

y luego

// in email.component.ts
import { HotMail } from './hot-mail';
...
...
export class EmailComponent {
  ...
  constructor(private emailService: HotMail) { }
  ...
}

Segundo, usando String (no recomendado ya que puede causar colisión de nombres), por ejemplo:

// in app.module.ts
import { HotMail } from './hot-mail';
...
...
...
@NgModule({
  providers: [
    {
      provide: 'EMS', // Here we are using string
      useClass: HotMail
    }
  ],
})
...
...

y luego

// in email.component.ts
import { Inject } from '@angular/core';
// Here we don't need to import HotMail
...
...
export class EmailComponent {
  ...
  constructor(@Inject('EMS') private emailService) { }
  ...
}

Tercero, utilizando InjectionToken (preferible al segundo método), por ejemplo:

// in app.module.ts
import { HotMail } from './hot-mail';
import { InjectionToken } from '@angular/core';
...
...
...
const AnyName = new InjectionToken<HotMail>('Any Message');
@NgModule({
  providers: [
    {
      provide: AnyName,
      useClass: HotMail
    }
  ],
})
...
...

y entonces, aquí está el problema, no pude encontrar una manera de cómo podemos consumir un token declarado usando InjectionToken, cuando ejecuto ng serve siempre devuelve un mensaje de error, por ejemplo cuando hago lo siguiente:

// in email.component.ts
import { Inject } from '@angular/core';
// Here we don't need to import HotMail
...
...
export class EmailComponent {
  ...
  constructor(@Inject(AnyName) private emailService) { }
  ...
}

Siempre vuelve

ERROR in ../../../email.component.ts: Cannot find name 'AnyName'

¿Cómo solucionar este problema?

Respuesta #1

Necesitas importar ese token en tu componente y luego inyectarlo. En un archivo separado puedes tener este token como miembro exportado

export const AnyName = new InjectionToken<HotMail>('Any Message');

Luego impórtalo en los archivos en los que quieras usarlo.

Respuesta #2

Necesitas exportarlo como lo harías con cualquier otra cosa

export const AnyName = new InjectionToken<HotMail>('Any Message');

y naturalmente importarlo como lo harías con cualquier otra cosa

import {Inject} from '@angular/core';
import {AnyName} from './m';

export default class {
  constructor(@Inject(AnyName) a) {...}
}