¿Qué hay en el token opaco de Angular 2 y cuál es el punto?
angular2-opaquetoken (4)
Me encuentro con ''tokens opacos'' como una solución para implementar constantes globales en Angular 2, por ejemplo aquí: Definir constantes globales en Angular 2
A pesar de leer los docs , parece que no puedo entender el punto.
Es preferible usar un OpaqueToken que usar cadenas como tokens debido a las posibles colisiones causadas por varios proveedores que usan la misma cadena que dos tokens diferentes.
¿Qué? ¿Qué es un token Angular2 para empezar? Todo lo que obtengo en Google son respuestas en los tokens web de JSON (su función en auth, etc, etc), que entiendo, pero obviamente no están relacionados de ninguna manera.
¿Qué es un token opaco? ¿Para qué se usa esto?
PS Más docs en tokens opacos utilizados para proporcionar constantes. Sin embargo, no me ayudaron mucho.
¿Qué es un token opaco? ¿Para qué se usa esto?
El token opaco utilizado para inyectar a otro proveedor (servicio) con el mismo nombre.
Esto le permite evitar nombrar colisiones.
const MY_HTTP_TOKEN: OpaqueToken = new OpaqueToken(''Http'');
providers: [
{ provide: MY_HTTP_TOKEN, useClass: Http }
]
constructor(@Inject(MY_HTTP_TOKEN) private myHttpService){}
Soy nuevo en angular 2, pero quiero intentar interpretar lo que entendí en https://blog.thoughtram.io/angular/2016/05/23/opaque-tokens-in-angular-2.html en un código simple CMIIW.
...
const CONFIG_ONE = {title: ''My awesome app''};
let configOneToken = ''config''; //''config'' is an example of string-type token
const CONFIG_TWO = {title: ''My fantastic app''};
let configTwoToken = ''config'';
providers = [
{ provide: configOneToken, useValue: CONFIG_ONE },
{ provide: configTwoToken, useValue: CONFIG_TWO }
];
Ese fragmento de código tendrá un problema (el último anulará al anterior) porque tiene un conflicto ( ''config'' == ''config''
). Puede ser demasiado obvio y sin sentido en ese código de juguete, pero en un código real, es posible que no podamos identificar este conflicto fácilmente cuando uno de los proveedores está definido en una biblioteca de terceros. Por lo tanto, para solucionarlo, podemos usar OpaqueToken como se muestra en el siguiente código.
...
const CONFIG_ONE = {title: ''My awesome app''};
const OPAQUE_TOKEN_ONE = new OpaqueToken(''config''); //this is an example of object-type token
const CONFIG_TWO = {title: ''My fantastic app''};
const OPAQUE_TOKEN_TWO = new OpaqueToken(''config'');
providers = [
{ provide: OPAQUE_TOKEN_ONE, useValue: CONFIG_ONE },
{ provide: OPAQUE_TOKEN_TWO, useValue: CONFIG_TWO }
];
Dos instancias de una misma clase nunca son iguales (¡ new OpaqueToken(''config'') != new OpaqueToken(''config'')
) y, por lo tanto, evita conflictos. El OpaqueToken
sí mismo no es más que una simple clase de no hacer nada.
Un token opaco es solo una clase de tiempo de ejecución que se utiliza como un identificador único para los proveedores de inyectores.
Digamos que tiene un valor, ''secretId'' que desea usar en algunos servicios y componentes. No desea codificar esto en sus servicios y componentes, ya que cambiará en el futuro. También desea escribir pruebas para sus servicios y componentes.
Con una clase puede usar la clase como una implementación, tipo y token de inyector. Para un valor de cadena, otras expresiones literales, objetos, etc., no tiene nada que usar como un token de inyector. Podría usar una cadena como un token de inyector, pero no hay ningún gruñido de que la cadena sea única. Con los tokens opacos, incluso si dos tokens tienen el mismo nombre, se evaluarán como tokens diferentes.
actualizar Angular4
En Angular4 OpaqueToken
está en desuso y será reemplazado por InjectionToken
. InjectionToken permite pasar un parámetro de tipo genérico.
export let APP_CONFIG = new InjectionToken<MyConfig>("app.config");
Ver también
original
¿Qué? ¿Qué es un token Angular2 para empezar?
¿Qué es un token opaco? ¿Para qué se usa esto?
Un token es una clave para los proveedores de inyección de dependencia Angulars. Los proveedores se registran con una clave y los componentes, directivas y clases de servicio instanciados por DI obtienen las dependencias inyectadas, que se consultan mediante claves de proveedor.
DI admite tipos, cadenas, OpaqueToken
y objetos como claves.
export let APP_CONFIG = new OpaqueToken("app.config");
export let APP_CONFIG_2 = {};
providers: [
MyService, // type is key and value
{provide: MyService, useClass: MyFancyServiceImpl}, // type is key, `MyFancyServiceImpl` is the value (or rather the information how to create the value
{provide: ''myservice'', useClass: MyService}, // key is a string
{provide: APP_CONFIG, useValue: {a: ''a'', b: ''b''}} // key is an `OpaqueToken`
{provide: APP_CONFIG_2, useValue: {a: ''a'', b: ''b''}} // key is an object
]
// one of these decorators needs to be added to make DI work
@Injectable()
@Component()
@Directive()
@Pipe()
class MyComponent {
// DI looks up a provider registered with the key `MyService`
constructor(private myService: MyService) {}
// Same as before but explicit
constructor(@Inject(MyService) private myService: MyService) {}
// DI looks up a provider registered with the key ''myService''
constructor(@Inject(''myservice'') private myService: MyService) {}
// DI looks up a provider registered with the `OpaqueKey` `APP_CONFIG`
constructor(@Inject(APP_CONFIG) private myConfig: any) {}
// DI looks up a provider registered with the object `APP_CONFIG_2`
constructor(@Inject(APP_CONFIG_2) private myConfig: any) {}
La clave de objeto ( APP_CONFIG_2
) y el OpaqueToken
( APP_CONFIG
) deben ser exactamente la misma instancia. Una instancia diferente con el mismo contenido no funcionará. Esto facilita la búsqueda de dónde se declara la clave y si el proveedor y el objetivo de inyección usan la misma clave.
Para una cadena puede ser una instancia diferente, esto conlleva el riesgo de que el mismo valor de cadena se use en diferentes módulos y pueda causar conflictos o la inyección del proveedor incorrecto.