Directiva personalizada de AngularJS: plantillas, ámbito y transclusión
⚡ Resumen inteligente
Las directivas personalizadas en AngularJS extienden HTML con un comportamiento reutilizable que usted mismo define. Una fábrica de directivas devuelve un objeto de definición, y AngularJS adjunta ese comportamiento dondequiera que aparezca el elemento, atributo, clase o comentario correspondiente en el marcado.

¿Qué es una directiva personalizada en AngularJS?
A Directiva personalizada En AngularJS, es una directiva definida por el usuario que extiende HTML con un comportamiento que usted mismo escribe. Se registra en un módulo utilizando la función “directiva”, y AngularJS la adjunta dondequiera que aparezca el elemento o atributo correspondiente en la página. Aunque AngularJS tiene muchas funciones potentes directivas integradas fuera de la caja, como por ejemplo ng-repetirEn ocasiones, se requieren directivas personalizadas.
⚠️ Corrección: El texto original decía que una directiva personalizada “reemplaza el elemento para el que se utiliza”. Por defecto, no lo hace: template se inserta interior el elemento coincidente. Se necesitan reemplazos replace: true, obsoleto desde AngularJS 1.3.
⚠️ Aviso de soporte: AngularJS alcanzó fin de vida el 31 de diciembre de 2021 y no recibe más parches ni correcciones de seguridad. Todo lo que se indica a continuación sigue siendo válido para el mantenimiento del código AngularJS 1.x existente; en Angular moderno, los equivalentes son los componentes y las directivas de atributos.
La razón para recurrir a una directiva personalizada es la repetición. Cuando el mismo marcado o la misma configuración del DOM aparece en varias pantallas, una directiva lo convierte en una sola etiqueta con nombre.
¿Cómo crear una directiva personalizada?
Veamos un ejemplo de cómo podemos crear una directiva personalizada en AngularJS.
En nuestro caso, la directiva personalizada simplemente insertará una etiqueta div con el texto "Tutorial de Angular JS" en nuestra página cuando se llame a la directiva.
La captura de pantalla anotada que aparece a continuación numera las cuatro partes del listado que se explican a continuación.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <div ng-guru=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('ngGuru',function(){ return { template: '<div>Angular JS Tutorial</div>' } }); </script> </body> </html>
⚠️ Advertencia: defectos que se conservan en este listado: El código se reproduce exactamente como se publicó. Tres fallos se repiten en cada listado: chrset="UTF 8" debiera ser charset="UTF-8"; angular.js y angular.min.js ambos se cargan, por lo que AngularJS se carga dos veces; y angular-route.js Se carga antes que el archivo del que depende.
Code Explicación
- Primero estamos creando un módulo Para nuestra aplicación AngularJS, es necesario crear una directiva personalizada, ya que esta se creará utilizando este módulo.
- Ahora estamos creando una directiva personalizada llamada “ngGuru” y definiendo una función de fábrica que contendrá el código personalizado para nuestra directiva.
- Estamos utilizando el parámetro de plantilla, que es un parámetro definido por AngularJS para directivas personalizadas. En este caso, definimos que cada vez que se utilice esta directiva, simplemente se use el valor de la plantilla y se inyecte en el código que la llama.
- Aquí estamos haciendo uso de nuestra directiva personalizada “ng-guru”. Cuando hacemos esto, el valor que definimos para nuestra plantilla,
<div>Angular JS Tutorial</div>, ahora se inyectará aquí.
Denominación y normalización de directivas
La discrepancia en el nombre entre el JavaEl lenguaje Script y el HTML confunden a la mayoría de los principiantes. AngularJS normaliza cada elemento y nombre de atributo antes de que coincida: elimina cualquier x- or data- prefijo, luego convierte un nombre delimitado por -, : or _ en camelCase. Por eso ngGuru cerillas ng-guru, y por qué data-ng-guru También funciona. El nombre real es camelCase; kebab-case es simplemente cómo se escribe en HTML.
⚠️ Corrección: El texto original decía que el nombre de una directiva personalizada “debería comenzar con las letras 'ng'”. Documentación oficial de AngularJS aconseja lo contrario: nunca anteponga a sus propias directivas ngo podrían entrar en conflicto con una función integrada futura. Utilice su propio prefijo, como por ejemplo: g99Guru Escrito como g99-guru.
Si el código se ejecuta correctamente, aparece esta salida.
Salida:
El resultado muestra claramente que nuestra directiva personalizada ng-guru, que tiene definida la plantilla para mostrar un texto personalizado, se visualiza en el navegador. El siguiente paso es insertar algo que valga la pena reutilizar dentro de esa plantilla.
Cómo crear directivas reutilizables
Ya vimos el poder de las directivas personalizadas, pero podemos llevarlo al siguiente nivel creando nuestras propias directivas reutilizables.
Digamos, por ejemplo, que quisiéramos inyectar código que mostrara siempre las siguientes etiquetas HTML en varias pantallas, que básicamente son solo un campo de entrada para el "Nombre" y la "edad" del usuario.
Para reutilizar este fragmento en varias pantallas sin tener que codificarlo cada vez, creamos un control maestro, o directiva, en AngularJS que contiene estos dos controles.
Ahora, en lugar de repetir ese marcado en cada pantalla, lo insertamos en una directiva y llamamos a la directiva. La captura de pantalla a continuación muestra la única línea que cambia.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <div ng-guru=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('ngGuru',function(){ return { template: ' Name <input type="text"><br><br> Age<input type="text">' }; }); </script> </body> </html>
Code Explicación
- En nuestro fragmento de código para una directiva personalizada, lo único que cambia es el valor que se le pasa al parámetro de la plantilla. En lugar de una etiqueta simple o una línea de texto, estamos ingresando el fragmento completo de dos controles de entrada para el "Nombre" y la "Edad" que deben mostrarse en nuestra página.
👍 Tip: Una plantilla tan larga debería estar en su propio archivo. Intercambiar template por la templateUrl: 'name-age.html'.
Si el código se ejecuta correctamente, aparece esta salida.
Salida:
Como se puede observar en el resultado anterior, el fragmento de código de la plantilla de la directiva personalizada se agrega a la página. La plantilla aún es estática, por lo que el siguiente paso es proporcionarle datos.
Directivas y ámbitos de AngularJS
El global Se define como el elemento que une el controlador con la vista, gestionando los datos entre la vista y el controlador.
Al crear directivas personalizadas de AngularJS, estas tendrán acceso por defecto al objeto scope del controlador padre. Se trata del mismo objeto scope, no de una copia.
De esta manera, resulta fácil para la directiva personalizada hacer uso de los datos que se pasan al controlador principal.
Veamos un ejemplo de cómo podemos usar el ámbito de un controlador padre en nuestra directiva personalizada. La siguiente captura de pantalla muestra los cuatro pasos.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp" ng-controller="DemoController"> <div ng-guru=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.controller('DemoController',function($scope) { $scope.tutorialName = "Angular JS"; }); app.directive('ngGuru',function(){ return { template: '<div>{{tutorialName}}</div>' } }); </script> </body> </html>
Code Explicación
- Primero creamos un controlador llamado “DemoController”. En este, definimos una variable llamada tutorialName y la adjuntamos al objeto scope en una sola instrucción:
$scope.tutorialName = "Angular JS". - En nuestra directiva personalizada, podemos llamar a la variable "tutorialName" usando una expresión. Esta variable sería accesible porque está definida en el controlador “DemoController”, que se convertiría en el padre de esta directiva.
- Hacemos referencia al controlador en una etiqueta div, que actuará como nuestra etiqueta div principal. Tenga en cuenta que esto debe hacerse primero para que nuestra directiva personalizada acceda a la variable tutorialName.
- Finalmente adjuntamos nuestra directiva personalizada "ng-guru" a nuestra etiqueta div.
Si el código se ejecuta correctamente, aparece esta salida.
Salida:
El resultado anterior muestra claramente que nuestra directiva personalizada "ng-guru" utiliza la variable de ámbito tutorialName en el controlador padre. Compartir el ámbito del controlador padre es conveniente, pero no siempre es lo que se desea.
Uso de controladores con directivas
AngularJS ofrece la facilidad de acceder a la variable miembro del controlador directamente desde directivas personalizadas sin la necesidad del objeto de alcance.
Esto se vuelve necesario en ocasiones porque una aplicación puede tener varios objetos de ámbito pertenecientes a varios controladores, por lo que existe una alta probabilidad de acceder por error al objeto de ámbito del controlador equivocado.
En tal caso, hay una manera de decir específicamente "Quiero acceder a este controlador" desde mi directiva.
Veamos un ejemplo de cómo podemos lograrlo. La captura de pantalla muestra los cuatro pasos numerados.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp" ng-controller="DemoController"> <div ng-guru99=""></div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.controller('DemoController',function() { this.tutorialName = "Angular"; }); app.directive('ngGuru99',function(){ return { controller: 'DemoController', controllerAs: 'ctrl', template: '{{ctrl.tutorialName}}' }; }); </script> </body> </html>
Code Explicación
- Primero creamos un controlador llamado “DemoController”. En él definiremos una variable llamada “tutorialName” y, en esta ocasión, en lugar de adjuntarla al objeto scope, la adjuntaremos directamente al controlador.
- En nuestra directiva personalizada, mencionamos específicamente que queremos usar el controlador "DemoController" usando la palabra clave del parámetro del controlador.
- Creamos una referencia al controlador usando el parámetro "controllerAs". Este parámetro está definido por AngularJS y es la forma de referenciar el controlador mediante un alias.
- Finalmente, en nuestra plantilla, estamos utilizando la referencia creada en el paso 3 y la variable miembro que se adjuntó directamente al controlador en el paso 1.
Nota: Es posible acceder a múltiples controladores en una directiva especificando los bloques respectivos del controlador, controllerAs y las instrucciones de plantilla. Para llegar a un con el futuro bebé En su lugar, utilice el controlador de la directiva. require.
Si el código se ejecuta correctamente, aparece esta salida.
Salida:
La salida muestra claramente que la directiva personalizada accede al DemoController y a la variable miembro tutorialName asociada, y muestra el texto "Angular". Ambos enfoques siguen leyendo desde un ámbito compartido, algo que un ámbito aislado impide.
Cómo difieren las vinculaciones de @, =, & y < en un ámbito aislado
Una directiva que comparte su ámbito padre solo puede usarse una vez por controlador, porque dos copias competirían por las mismas variables. scope El objeto crea un alcance de aislamientoLa directiva no ve nada externo excepto las propiedades que usted enumera. Cada entrada utiliza un símbolo de prefijo que declara cómo se transmite su valor.
| Símbolo | SENTIDO DE SALIDA: | Valor recibido | Usalo para |
|---|---|---|---|
| @ | Entrada de sentido único | El atributo como una cadena interpolada | Etiquetas, títulos, cualquier texto sin formato |
| = | De doble sentido | El objeto vivo o valor en sí mismo | Modelos a los que la directiva escribe de vuelta |
| & | Llamada externa | Una función que evalúa una expresión en el ámbito externo. | Funciones de devolución de llamada como al cerrar o al guardar |
| < | Entrada de sentido único | El valor evaluado, nunca escrito en orden ascendente | Datos de solo lectura, añadidos en AngularJS 1.5. |
👍 Tip: Alcanzar < antes =El enlace unidireccional es más económico de observar y evita que un componente modifique silenciosamente los datos de quien lo llama. La siguiente sección utiliza @.
Directivas y componentes de AngularJS: ng-transclude
Como mencionamos anteriormente, AngularJS está diseñado para extender la funcionalidad de HTML. Y ya hemos visto cómo podemos inyectar código mediante el uso de directivas reutilizables personalizadas.
Pero en el desarrollo de aplicaciones web modernas, también existe el concepto de desarrollo.ping componentes web, lo que básicamente significa crear nuestras propias etiquetas HTML que se puedan utilizar como componentes en nuestro código.
Por lo tanto, AngularJS proporciona otro nivel de potencia para extender las etiquetas HTML, al brindar la capacidad de envolver cualquier marcado que el llamador coloque dentro de la etiqueta.
Esto lo hace el “ng-transcluirdirectiva ”, que le indica a AngularJS que capture todo lo que se coloque dentro de la etiqueta personalizada en el marcado y lo inserte en la plantilla en ese punto.
Veamos un ejemplo de cómo podemos lograrlo. La captura de pantalla muestra los cinco puntos que se detallan a continuación.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <pane title="{{title}}">Angular JS</pane> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('pane',function(){ return { transclude:true, scope :{title:'@'}, template: '<div style="border: 1px solid black;"> '+ '<ng-transclude></ng-transclude>'+ '</div>' }; }); </script> </body> </html>
Code Explicación
- Estamos utilizando la directiva para definir una etiqueta HTML personalizada llamada "pane", cuyo código se proporciona mediante una función de fábrica. En el resultado, la etiqueta "pane" muestra el texto "Angular JS" dentro de un rectángulo con un borde negro sólido.
- La propiedad “transclude” debe establecerse en verdadero, que es lo que le indica a AngularJS que mantenga el marcado interno original y lo ponga a disposición de
ng-transclude. - En el objeto scope estamos declarando una vinculación de título. Los atributos normalmente se escriben como pares nombre/valor como
name="value"En nuestro caso, el atributo en la etiqueta del panel es "title", y el símbolo "@" le pide a AngularJS que copie ese atributo como una cadena interpolada. - La plantilla dibuja el borde negro sólido para nuestro control y marca el lugar donde se inserta el marcado transcluido.
- Finalmente, estamos llamando a nuestra etiqueta HTML personalizada junto con el atributo de título que se definió.
⚠️ Corrección: El texto original describía “@” como “el requisito de Angular”. No es una formalidad: @ es uno de los cuatro símbolos de enlace de ámbito aislado en la tabla anterior y siempre produce una cadena. Esta plantilla tampoco renderiza nunca {{title}}y ningún controlador define title, por lo que solo es visible el texto transcluido.
Si el código se ejecuta correctamente, aparece esta salida.
Salida:
- El resultado muestra el elemento del panel personalizado representado como un cuadro con borde que contiene el texto transcluido "Angular JS".
Una directiva también puede contener otras directivas, que es como se ensamblan componentes más grandes.
Directivas anidadas
Las directivas en AngularJS se pueden anidar. Al igual que los módulos internos o las funciones en cualquier lenguaje de programación, es posible que deba incorporar directivas entre sí.
Puede comprender mejor esto viendo el siguiente ejemplo.
En este ejemplo, estamos creando 2 directivas llamadas "exterior" e "interior".
- La directiva interna muestra un texto llamado "Interior".
- Mientras que la directiva externa en realidad llama a la directiva interna para mostrar el texto llamado "Interior".
La captura de pantalla que aparece a continuación muestra las definiciones de ambas directivas y el punto en el que una llama a la otra.
</head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <outer></outer> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('outer',function(){ return { restrict:'E', template: '<div><h1>Outer</h1><inner></inner></div>', }}); app.directive('inner',function(){ return { restrict:'E', template: '<div><h1>Inner</h1></div>', } }); </script> </body> </html>
⚠️ Advertencia: defecto conservado en este listado: El listado publicado comienza en </head>, perdiéndose su apertura <!DOCTYPE html>, <html> y <head> líneas. Agrégalas antes de ejecutarlo.
Code Explicación
- Estamos creando una directiva llamada "externa" que se comportará como nuestra directiva principal. Esta directiva luego hará un llamado a la directiva "interna".
- El
restrict:'E'La opción le indica a AngularJS que haga coincidir cada directiva por nombre, por eso se pueden escribir como etiquetas<outer>y<inner>La letra 'E' es la forma abreviada de la palabra 'Elemento'. - Aquí estamos creando la directiva interna que muestra el texto "Interior" en una etiqueta div.
- En la plantilla de la directiva externa, estamos llamando a la directiva interna. Por lo tanto, aquí estamos inyectando la plantilla de la directiva interna en la directiva externa.
- Finalmente, estamos llamando directamente a la directiva externa.
⚠️ Corrección: El texto original afirmaba restrict:'E' Se requiere “para garantizar que los datos de la directiva interna estén disponibles para la directiva externa”. No hace tal cosa; solo controla cómo Se puede escribir una directiva. El anidamiento funciona porque el compilador sigue entrando en la plantilla que acaba de insertar. Para compartir datos, utilice require y controller.
Si el código se ejecuta correctamente, aparece esta salida.
Salida:
Desde la salida,
- Se puede observar que se han llamado tanto a la directiva externa como a la interna, y que el texto dentro de ambas etiquetas div se muestra correctamente.
Renderizar el marcado es solo la mitad de lo que hace una directiva; la otra mitad es reaccionar ante el usuario.
Manejo de eventos en una directiva
Eventos Las acciones como clics de ratón o de botón se pueden gestionar desde las propias directivas. Esto se logra mediante la función `link`. Esta función permite que la directiva se asocie a los elementos DOM de una página HTML.
Sintaxis:
La sintaxis de la función de enlace es la que se muestra a continuación.
link: function ($scope, element, attrs)
La función de enlace normalmente acepta 3 parámetros: el ámbito, el elemento al que está asociada la directiva y los atributos del elemento de destino. Dos parámetros más, un controlador obligatorio y una función de transclusión, se reciben cuando se aplican.
Fase de compilación versus fase de enlace
AngularJS procesa una directiva en dos fases, y saber cuál es cuál te indica dónde debe ir tu código.
- Compilar Se ejecuta una sola vez en el elemento de la plantilla, antes de que exista cualquier ámbito. Es adecuado para ediciones estructurales compartidas por cada clon.
- Enlace Se ejecuta una vez por instancia, después de que se clona la plantilla y se le asigna un ámbito. Los detectores de eventos DOM y las lecturas de ámbito pertenecen a este paso.
Debido a que compile no tiene ámbito, todo lo que necesite datos pertenece a link, razón por la cual el siguiente ejemplo define link solo.
Veamos un ejemplo de cómo podemos lograrlo. La captura de pantalla muestra los cuatro puntos que aparecen a continuación.
<!DOCTYPE html> <html> <head> <meta chrset="UTF 8"> <title>Event Registration</title> </head> <body> <script src="https://code.angularjs.org/1.6.9/angular-route.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <script src="https://code.angularjs.org/1.6.9/angular.min.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <h1> Guru99 Global Event</h1> <div ng-app="DemoApp"> <div ng-guru="">Click Me</div> </div> <script type="text/javascript"> var app = angular.module('DemoApp',[]); app.directive('ngGuru',function(){ return { link:function($scope,element,attrs) { element.bind('click',function () { element.html('You clicked me'); });} }}); </script> </body> </html>
Code Explicación
- Estamos utilizando la función link, tal como se define en AngularJS, para otorgar a la directiva la capacidad de acceder a eventos en el DOM de HTML.
- Utilizamos la palabra clave 'element' porque queremos responder a un evento de un elemento DOM de HTML, que en nuestro caso es el elemento 'div'. A continuación, usamos la función 'bind' para añadir funcionalidad personalizada al evento de clic de dicho elemento. La palabra clave 'click' se utiliza para indicar el evento de clic de cualquier control HTML.
- Aquí estamos diciendo que queremos sustituir el HTML interno del elemento, en nuestro caso el elemento div, con el texto 'Me hiciste clic'.
- Aquí estamos definiendo nuestra etiqueta div para usar la directiva personalizada ng-guru.
👍 Tip: Una directiva debe limpiar después de sí misma. Elimine cualquier oyente que sobreviva al elemento dentro. element.on('$destroy', ...)o la página tiene fugas de memoria.
Si el código se ejecuta correctamente, aparece esta salida.
Salida:
- Inicialmente, se muestra al usuario el texto "Haz clic aquí", ya que así se definió dentro de la etiqueta div. Al hacer clic en la etiqueta div, se muestra el siguiente resultado.
Cada ejemplo anterior utilizó una o dos propiedades del mismo objeto de definición. Vale la pena conservar el conjunto completo.ping a mano.
Referencia de propiedades de objetos de definición de directiva
El objeto devuelto por una fábrica de directivas es el Objeto de definición de directivaCada propiedad responde a una pregunta sobre cómo se comporta la directiva.
| Propiedad | Predeterminado | ¿Qué hace? |
|---|---|---|
| restringir | 'EA' | ¿Qué formas coinciden?: Elemento E, atributo A, clase C, comentario M |
| plantilla | ninguna | Marcado en línea insertado en el elemento coincidente |
| URL de la plantilla | ninguna | Ruta del archivo de plantilla, se obtiene una vez y luego se almacena en caché. |
| global | false | falso comparte el ámbito del padre, verdadero crea un hijo, un objeto aísla |
| controlador | ninguna | Constructor que expone una API otras directivas pueden requerir |
| controladorAs | ninguna | Alias para el controlador dentro de la plantilla |
| exigir | ninguna | Otro controlador de directiva para inyectar; ^ busca padres, ^^ se salta a sí mismo, ? opcional |
| este enlace | ninguna | Función por instancia: ámbito, elemento, atributos, controlador, transcludeFn |
| compilar | ninguna | Se ejecuta una vez en la plantilla antes de que exista cualquier ámbito. |
| transcluir | false | Conserva el marcado interno original para ng-transclude |
| lista de prioridades | 0 | Orden de compilación en un elemento compartido; el orden más alto se ejecuta primero. |
| terminal | false | Detiene las directivas de menor prioridad en ese elemento. |
| reemplazar | false | Reemplaza el elemento por la plantilla. Obsoleto desde la versión 1.3. |
👍 Tip: Comience con restrict, template y link. Añadir scope para su reutilización, controller y require para llamadas de directiva a directiva, y salir priority y terminal solo.
















