¿Qué son los "decoradores" y cómo se usan?

148

Tengo curiosidad por saber qué son exactamente los decoradores en AngularJS. No hay mucha información en línea para los decoradores, excepto por una propaganda en la documentación de AngularJS y una breve (aunque interesante) mención en un video de YouTube .

Como dicen los chicos de Angular, un decorador es:

Decoración del servicio, permite al decorador interceptar la creación de la instancia del servicio. La instancia devuelta puede ser la instancia original o una nueva instancia que delegue a la instancia original.

Realmente no sé qué significa eso , y no estoy seguro de por qué separarías esta lógica del servicio en sí. Por ejemplo, si quisiera devolver algo diferente en diferentes condiciones, simplemente pasaría diferentes argumentos a las funciones relevantes o usaría otra función que comparta ese estado privado.

Todavía soy una especie de novato de AngularJS, así que estoy seguro de que es solo ignorancia y / o malos hábitos lo que aprendí.

Kevin Beal
fuente

Respuestas:

219

Un caso de uso de buena $provide.decoratores cuando se necesita hacer menor "pellizco" en alguna de terceros / servicio de aguas arriba, de la que depende su módulo, dejando intacto el servicio (ya que no es el propietario / mantenedor del servicio). Aquí hay una demostración en plunkr.

tamakisquare
fuente
66
Impresionante ejemplo. En realidad, me preguntaba cómo extender la funcionalidad de los módulos de terceros sin interferir con ellos
Arthur Kovacs,
55
¿Los decoradores en realidad escriben de manera incorrecta todas las instancias de un servicio, o se limitan al módulo que los decora? En otras palabras, digamos que tengo el módulo A que decora un servicio del módulo B. Luego tengo el módulo C que depende del módulo A y el módulo B. Dentro del módulo C, ¿es el servicio del módulo B la versión original o decorada?
Jon Jaques
3
@JonJaques - Esa es una gran pregunta. No me he encontrado con tal situación. Si tuviera que adivinar, la versión del servicio que ve el módulo C debería ser la decorada del módulo A, pero no puedo decirlo con seguridad hasta que lo pruebe yo mismo. ¿Por qué no escribes un plunkr / jsffidle simple y experimentas con eso? Sería increíble si pudieras compartir tu hallazgo con nosotros. Salud.
tamakisquare
66
@JonJaques: no pude contener mi curiosidad, así que agregué algunas líneas a mi ejemplo original para encontrar la respuesta a su pregunta, enlace . En resumen, la suposición en mi comentario anterior es correcta.
tamakisquare
17
Las fábricas, los servicios, etc. son únicos (según se proporcionan), por lo que una vez decorados, siempre decorados.
FlavorScape
66

Los decoradores nos permiten separar las preocupaciones transversales y permiten que los servicios preserven el principio de responsabilidad única sin preocuparse por el código de "infraestructura".

Usos prácticos de decoradores:

  • Almacenamiento en caché: si tenemos un servicio que realiza llamadas HTTP potencialmente costosas, podemos envolver el servicio en un decorador de almacenamiento en caché que verifica el almacenamiento local antes de realizar la llamada externa.
  • Depuración / seguimiento: tenga un interruptor según su configuración de desarrollo / producción que decore sus servicios con envolturas de depuración o seguimiento.
  • Regulación: ajusta las llamadas que se desencadenan con frecuencia en un contenedor antirrebote. Nos permite interactuar fácilmente con servicios de tarifa limitada, por ejemplo.

En todos estos casos, limitamos el código del servicio a su responsabilidad principal.

JBland
fuente
10

decoratorpuede interceptar la instancia de servicio creada por factory, service, value, provider, y brinda las opciones para cambiar alguna instance(service)que de otro modo no sería configurable / con opciones.

También puede proporcionar instancias simuladas para fines de prueba, por ejemplo $http.

Daiwei
fuente
1
Vale la pena señalar que también puede anular las directivedefiniciones presentadas por Ben Nadel
David Salamon
Aquí está la referencia en los documentos oficiales de Angular: https://docs.angularjs.org/guide/decorators
David Salamon
3

En palabras simples, podemos decir que es como un método de extensión. Por ej. Tenemos una clase y tiene dos métodos y en el tiempo de ejecución queremos agregar más métodos y luego usar Decorator.

No podemos usar $ provide.decorator con constantes porque no podemos cambiar las constantes que están cargando la propiedad de solo lectura.

Gurupreet
fuente
1

En resumen, los decoradores se pueden describir de la siguiente manera:

Una función decoradora intercepta la creación de un servicio, lo que le permite anular o modificar el comportamiento del servicio.

Utiliza el $provideservicio por angular y modifica o reemplaza la implementación de otro servicio

$provide.decorator('service to decorate',['$delegate', function($delegate) {
  // $delegate - The original service instance, 
  //             which can be replaced, monkey patched, 
  //             configured, decorated or delegated to. 
  //             ie here what is there in the 'service to decorate'

  //   This function will be invoked, 
  //   when the service needs to be provided 
  //   and should return the decorated service instance.
  return $delegate;
}]);

Ejemplo:

$provide.decorator('$log', ['$delegate', function($delegate) {
  // This will change implementation of log.war to log.error
  $delegate.warn = $delegate.error; 
  return $delegate;
}]);

Aplicaciones

Además de la respuesta @JBland.

  • Configuración de configuración regional amplia de la aplicación: -

    Puedes encontrar un ejemplo aquí

  • Changiging comportamiento predeterminado e implementación existente de un servicio por servicio angular: -

    Puedes encontrar un ejemplo aquí

  • Cambio de comportamiento de una función en diferentes entornos.

samuelj90
fuente