Buscar..


Introducción

Aquí aprenderá sobre la característica de directivas de AngularJS. A continuación encontrará información sobre qué son las directivas, así como ejemplos básicos y avanzados de cómo usarlas.

Parámetros

Parámetro Detalles
alcance Propiedad para establecer el alcance de la directiva. Se puede establecer como falso, verdadero o como un alcance aislado: {@, =, <, &}.
alcance: falsy La directiva utiliza el ámbito primario. No hay ámbito creado para directiva.
alcance: verdadero La directiva hereda prototípicamente el ámbito principal como nuevo ámbito secundario. Si hay varias directivas en el mismo elemento que solicitan un nuevo alcance, entonces compartirán un nuevo alcance.
alcance: {@} Enlace unidireccional de una propiedad de ámbito de directiva a un valor de atributo DOM. A medida que el valor del atributo se enlaza en el padre, cambiará en el ámbito de la directiva.
alcance: {=} Enlace de atributo bidireccional que cambia el atributo en el padre primario si el atributo de la directiva cambia y viceversa.
alcance: {<} Enlace unidireccional de una propiedad de ámbito de directiva y una expresión de atributo DOM. La expresión se evalúa en el padre. Esto vigila la identidad del valor principal, por lo que los cambios en una propiedad de objeto en el elemento primario no se reflejarán en la directiva. Los cambios en una propiedad de objeto en una directiva se reflejarán en el elemento primario, ya que ambos hacen referencia al mismo objeto
alcance: {&} Permite que la directiva pase datos a una expresión para ser evaluada en el padre.
compilar: función Esta función se utiliza para realizar la transformación DOM en la plantilla directiva antes de que se ejecute la función de enlace. Acepta tElement (la plantilla de directiva) y tAttr (lista de atributos declarados en la directiva). No tiene acceso al ámbito de aplicación. Puede devolver una función que se registrará como una función de post-link o puede devolver un objeto con propiedades pre y post con el que se registrará como funciones de post-link pre-link y post-link .
enlace: función / objeto La propiedad de enlace se puede configurar como una función u objeto. Puede recibir los siguientes argumentos: alcance (ámbito de la directiva), iElement (elemento DOM donde se aplica la directiva), iAttrs (colección de atributos del elemento DOM), controlador (matriz de controladores requeridos por la directiva), transcludeFn. Se utiliza principalmente para configurar escuchas de DOM, ver las propiedades del modelo en busca de cambios y actualizar el DOM. Se ejecuta después de clonar la plantilla. Se configura de forma independiente si no hay una función de compilación.
función de enlace previo Función de enlace que se ejecuta antes que cualquier función de enlace hijo. De forma predeterminada, las funciones de enlace de directiva secundaria se ejecutan antes que las funciones de enlace de directiva principal y la función de enlace previo permite al enlace primario primero. Un caso de uso es si el niño requiere datos del padre.
función de enlace posterior Función de enlace que los ejecutivos después de los elementos secundarios están vinculados al padre. Por lo general, se usa para adjuntar controladores de eventos y acceder a directivas secundarias, pero los datos requeridos por la directiva secundaria no deben establecerse aquí porque la directiva secundaria ya estará vinculada.
restringir: cadena Define cómo llamar a la directiva desde el DOM. Valores posibles (Suponiendo que nuestro nombre de directiva sea demoDirective ): E - Nombre del elemento ( <demo-directive></demo-directive> ), A - Atributo ( <div demo-directive></div> ), C - Clase correspondiente ( <div class="demo-directive"></div> ), M - Por comentario ( <!-- directive: demo-directive --> ). La propiedad de restrict también puede admitir múltiples opciones, por ejemplo, restrict: "AC" restringirá la directiva a Atributo O Clase . Si se omite, el valor predeterminado es "EA" (Elemento o Atributo).
requiere: 'demoDirective' Localice el controlador de demoDirective en el elemento actual e inyecte su controlador como el cuarto argumento de la función de enlace. Lanzar un error si no se encuentra.
requiere: '? demoDirective' Intente ubicar el controlador demoDirective o pase el nulo al enlace fn si no lo encuentra.
requiere: '^ demoDirective' Localice el controlador de demoDirective buscando el elemento y sus padres. Lanzar un error si no se encuentra.
requiere: '^^ demoDirective' Localice el controlador de demoDirective buscando los padres del elemento. Lanzar un error si no se encuentra.
requiere: '? ^ demoDirective' Intente ubicar el controlador de demoDirective buscando el elemento y sus padres o pase el nulo al enlace fn si no lo encuentra.
require: '? ^^ demoDirective' Intente localizar el controlador de demoDirective buscando los elementos principales del elemento, o pase el nulo al enlace fn si no lo encuentra.

Crear y consumir directivas personalizadas.

Las directivas son una de las características más poderosas de angularjs. Las directivas angulosas personalizadas se usan para ampliar la funcionalidad de html creando nuevos elementos html o atributos personalizados para proporcionar cierto comportamiento a una etiqueta html.

directiva.js

// Create the App module if you haven't created it yet
var demoApp= angular.module("demoApp", []);

// If you already have the app module created, comment the above line and create a reference of the app module
var demoApp = angular.module("demoApp"); 


// Create a directive using the below syntax
// Directives are used to extend the capabilities of html element 
// You can either create it as an Element/Attribute/class      
// We are creating a directive named demoDirective. Notice it is in CamelCase when we are defining the directive just like ngModel
// This directive will be activated as soon as any this element is encountered in html

demoApp.directive('demoDirective', function () {
    
  // This returns a directive definition object
  // A directive definition object is a simple JavaScript object used for configuring the directive’s behaviour,template..etc
  return {
    // restrict: 'AE', signifies that directive is Element/Attribute directive, 
    // "E" is for element, "A" is for attribute, "C" is for class, and "M" is for comment. 
    // Attributes are going to be the main ones as far as adding behaviors that get used the most.
    // If you don't specify the restrict property it will default to "A"
    restrict :'AE',  

    // The values of scope property decides how the actual scope is created and used inside a directive. These values can be either “false”, “true” or “{}”. This creates an isolate scope for the directive.
    // '@' binding is for passing strings. These strings support {{}} expressions for interpolated values.
    // '=' binding is for two-way model binding. The model in parent scope is linked to the model in the directive's isolated scope.
    // '&' binding is for passing a method into your directive's scope so that it can be called within your directive. 
    // The method is pre-bound to the directive's parent scope, and supports arguments.
    scope: { 
      name: "@",  // Always use small casing here even if it's a mix of 2-3 words
    },                  

    // template replaces the complete element with its text. 
    template: "<div>Hello {{name}}!</div>",
                
    // compile is called during application initialization. AngularJS calls it once when html page is loaded.
    compile: function(element, attributes) {
      element.css("border", "1px solid #cccccc");
                    
      // linkFunction is linked with each element with scope to get the element specific data.
      var linkFunction = function($scope, element, attributes) {
        element.html("Name: <b>"+$scope.name +"</b>");
        element.css("background-color", "#ff00ff");
      };
      return linkFunction;
    }
  };
});

Esta directiva se puede utilizar en la aplicación como:

<html>
   
   <head>
      <title>Angular JS Directives</title>
   </head>
   <body>
   <script src = "//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
   <script src="directive.js"></script>   
    <div ng-app = "demoApp">
       <!-- Notice we are using Spinal Casing here -->  
       <demo-directive name="World"></demo-directive>
     
      </div>
   </body>
</html>

Directiva de plantilla de objeto de definición

demoApp.directive('demoDirective', function () {
  var directiveDefinitionObject = {
    multiElement:  
    priority:
    terminal:
    scope: {},  
    bindToController: {},
    controller:
    controllerAs:
    require:
    restrict:
    templateNamespace:
    template:
    templateUrl:
    transclude:
    compile: 
    link: function(){}                                  
  };
  return directiveDefinitionObject;
});
  1. multiElement - establecido en verdadero y todos los nodos DOM entre el inicio y el final del nombre de la directiva se recopilarán y agruparán como elementos de la directiva
  2. priority : permite la especificación del orden para aplicar directivas cuando se definen múltiples directivas en un solo elemento DOM. Las directivas con números más altos se compilan primero.
  3. terminal : se establece en verdadero y la prioridad actual será el último conjunto de directivas para ejecutar
  4. scope : establece el ámbito de la directiva.
  5. bind to controller : vincula las propiedades del ámbito directamente al controlador de directivas
  6. controller - función constructor controlador
  7. require - requiere otra directiva e inyectar su controlador como el cuarto argumento de la función de enlace.
  8. controllerAs : referencia de nombre al controlador en el ámbito de la directiva para permitir que se haga referencia al controlador desde la plantilla de la directiva.
  9. restrict : restringir la directiva a Elemento, Atributo, Clase o Comentario
  10. templateNameSpace : establece el tipo de documento utilizado por la plantilla de directiva: html, svg o math. html es el predeterminado
  11. template : marca html que por defecto reemplaza el contenido del elemento de la directiva, o envuelve el contenido del elemento de la directiva si la transclusión es verdadera
  12. templateUrl - url proporcionada de forma asíncrona para la plantilla
  13. transclude : extraiga el contenido del elemento donde aparece la directiva y haga que esté disponible para la directiva. Los contenidos se compilan y se proporcionan a la directiva como una función de transclusión.
  14. compile - función para transformar la plantilla DOM
  15. link : solo se utiliza si la propiedad de compilación no está definida. La función de enlace es responsable de registrar los escuchas de DOM y de actualizar el DOM. Se ejecuta después de que la plantilla ha sido clonada.

Ejemplo de directiva básica

superman-directiva.js

angular.module('myApp', [])
  .directive('superman', function() {
    return {
      // restricts how the directive can be used
      restrict: 'E',
      templateUrl: 'superman-template.html',
      controller: function() {
        this.message = "I'm superman!"
      },
      controllerAs: 'supermanCtrl',
      // Executed after Angular's initialization. Use commonly 
      // for adding event handlers and DOM manipulation
      link: function(scope, element, attributes) {
        element.on('click', function() {
          alert('I am superman!')
        });
      }
    }
  });

superman-template.html

<h2>{{supermanCtrl.message}}</h2>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
  <script src="superman-directive.js"><script/>
</head>
<body>
<div ng-app="myApp">
  <superman></superman>
</div>
</body>
</html>

Puede consultar más sobre las funciones de restrict y link la directiva en la documentación oficial de AngularJS sobre directivas

Cómo crear un componente resuable usando una directiva.

Las directivas AngularJS son las que controlan la representación del HTML dentro de una aplicación AngularJS. Pueden ser un elemento HTML, atributo, clase o un comentario. Las directivas se utilizan para manipular el DOM, adjuntando nuevos comportamientos a elementos HTML, enlace de datos y muchos más. Algunos de los ejemplos de directivas que proporciona angular son ng-model, ng-hide, ng-if.

Del mismo modo, uno puede crear su propia directiva personalizada y hacerlos valiosos. Para crear referencias de directivas personalizadas. El sentido detrás de la creación de directivas reutilizables es hacer un conjunto de directivas / componentes escritos por usted, tal como angularjs nos proporciona el uso de angular.js. Estas directivas reutilizables pueden ser particularmente muy útiles cuando tiene un conjunto de aplicaciones / aplicación que requiere un comportamiento y apariencia consistentes. Un ejemplo de dicho componente reutilizable puede ser una barra de herramientas simple que puede usar en su aplicación o en diferentes aplicaciones, pero desea que se comporten igual o se vean igual.

En primer lugar, cree una carpeta llamada resuableComponents en la carpeta de su aplicación y haga reutilizableModuleApp.js

reutilizableModuleApp.js:

(function(){

 var reusableModuleApp = angular.module('resuableModuleApp', ['ngSanitize']);

 //Remember whatever dependencies you have in here should be injected in the app module where it is intended to be used or it's scripts should be included in your main app  
                               //We will be injecting ng-sanitize

 resubaleModuleApp.directive('toolbar', toolbar)

 toolbar.$inject=['$sce'];

 function toolbar($sce){

     return{ 
     restrict :'AE',
        //Defining below isolate scope actually provides window for the directive to take data from app that will be using this.
        scope : {
                value1: '=',
                value2: '=',
                },

         }
     template : '<ul>  <li><a ng-click="Add()" href="">{{value1}}</a></li>  <li><a ng-click="Edit()" href="#">{{value2}}</a></li> </ul> ',
         link : function(scope, element, attrs){
           
              //Handle's Add function
              scope.Add = function(){


              };

              //Handle's Edit function
              scope.Edit = function(){

              };
     }
  }

});

mainApp.js:

(function(){
   var mainApp = angular.module('mainApp', ['reusableModuleApp']); //Inject resuableModuleApp in your application where you want to use toolbar component
   
   mainApp.controller('mainAppController', function($scope){
      $scope.value1 = "Add";
      $scope.value2 = "Edit"; 
   
   });
 
 });

index.html:

 <!doctype html>
 <html ng-app="mainApp">
 <head>
  <title> Demo Making a reusable component
 <head>
  <body ng-controller="mainAppController">
   
     <!-- We are providing data to toolbar directive using mainApp'controller -->
     <toolbar value1="value1" value2="value2"></toolbar>
  
    <!-- We need to add the dependent js files on both apps here -->
     <script src="js/angular.js"></script>
     <script src="js/angular-sanitize.js"></script>
    
     <!-- your mainApp.js should be added afterwards --->
      <script src="mainApp.js"></script>

     <!-- Add your reusable component js files here -->
      <script src="resuableComponents/reusableModuleApp.js"></script>

  </body>
 </html>

Las directivas son componentes reutilizables por defecto. Cuando hace directivas en un módulo angular separado, en realidad lo hace exportable y reutilizable en diferentes aplicaciones angulares. Las nuevas directivas simplemente se pueden agregar dentro de reusableModuleApp.js y reusableModuleApp puede tener su propio controlador, servicios, objeto DDO dentro de la directiva para definir el comportamiento.

Directiva básica con plantilla y un alcance aislado.

La creación de una directiva personalizada con alcance aislado separará el alcance dentro de la directiva del alcance externo , a fin de evitar que nuestra directiva cambie accidentalmente los datos en el alcance principal y restrinja la lectura de datos privados del alcance principal.

Para crear un alcance aislado y aún permitir que nuestra directiva personalizada se comunique con el alcance externo, podemos usar la opción de scope que describe cómo asignar los enlaces del ámbito interno de la directiva con el alcance externo.

Los enlaces reales se realizan con atributos adicionales adjuntos a la directiva. Las configuraciones de enlace se definen con la opción de scope y un objeto con pares clave-valor:

  • Una clave , que se corresponde con la propiedad de alcance aislado de nuestra directiva.
  • Un valor , que le indica a Angular cómo vincular el ámbito interno de la directiva a un atributo coincidente

Ejemplo simple de una directiva con un alcance aislado:

var ProgressBar = function() {
  return {
    scope: { // This is how we define an isolated scope
      current: '=', // Create a REQUIRED bidirectional binding by using the 'current' attribute
      full: '=?maxValue' // Create an OPTIONAL (Note the '?'): bidirectional binding using 'max-value' attribute to the `full` property in our directive isolated scope 
    }
    template: '<div class="progress-back">' +
              '  <div class="progress-bar"' +
              '       ng-style="{width: getProgress()}">' +
              '  </div>' + 
              '</div>',
    link: function(scope, el, attrs) {
      if (scope.full === undefined) {
        scope.full = 100;
      }
      scope.getProgress = function() {
        return (scope.current / scope.size * 100) + '%';
      }
    }
  }
}

ProgressBar.$inject = [];
angular.module('app').directive('progressBar', ProgressBar);

Ejemplo de cómo usar esta directiva y vincular los datos del alcance del controlador al alcance interno de la directiva:

Controlador:

angular.module('app').controller('myCtrl', function($scope) {
    $scope.currentProgressValue = 39;
    $scope.maxProgressBarValue = 50;
});

Ver:

<div ng-controller="myCtrl">
    <progress-bar current="currentProgressValue"></progress-bar>
    <progress-bar current="currentProgressValue" max-value="maxProgressBarValue"></progress-bar>
</div>

Construyendo un componente reutilizable.

Las directivas se pueden utilizar para construir componentes reutilizables. Aquí hay un ejemplo de un componente de "carpeta de usuario":

userBox.js

angular.module('simpleDirective', []).directive('userBox', function() {
  return {
    scope: {
        username: '=username',
        reputation: '=reputation'
    },
    templateUrl: '/path/to/app/directives/user-box.html'
  };
});

Controller.js

var myApp = angular.module('myApp', ['simpleDirective']);

myApp.controller('Controller', function($scope) {

    $scope.user = "John Doe";
    $scope.rep = 1250;

    $scope.user2 = "Andrew";
    $scope.rep2 = 2850;

});

myPage.js

<html lang="en" ng-app="myApp">
  <head>
    <script src="/path/to/app/angular.min.js"></script>
    <script src="/path/to/app/js/controllers/Controller.js"></script>
    <script src="/path/to/app/js/directives/userBox.js"></script>
  </head>

  <body>
  
    <div ng-controller="Controller">
        <user-box username="user" reputation="rep"></user-box>
        <user-box username="user2" reputation="rep2"></user-box>
    </div>
    
  </body>
</html>

user-box.html

<div>{{username}}</div>
<div>{{reputation}} reputation</div>

El resultado será:

John Doe
1250 reputation
Andrew
2850 reputation

Directivo decorador

A veces es posible que necesite características adicionales de una directiva. En lugar de reescribir (copiar) la directiva, puede modificar el comportamiento de la directiva.

El decorador será ejecutado durante la fase de inyección.

Para ello, provea un .config a su módulo. La directiva se llama myDirective, por lo que tiene que configurar myDirectiveDirective. (esto en una convención angular [leer sobre proveedores]).

Este ejemplo cambiará el templateUrl de la directiva:

angular.module('myApp').config(function($provide){
        $provide.decorator('myDirectiveDirective', function($delegate){
             var directive = $delegate[0]; // this is the actual delegated, your directive
             directive.templateUrl = 'newTemplate.html'; // you change the directive template
        return $delegate;
    })
});

Este ejemplo agrega un evento onClick al elemento directivo cuando se hace clic, esto sucede durante la fase de compilación.

angular.module('myApp').config(function ($provide) {
        $provide.decorator('myDirectiveTwoDirective', function ($delegate) {
            var directive = $delegate[0];
            var link = directive.link; // this is directive link phase
            directive.compile = function () { // change the compile of that directive
                return function (scope, element, attrs) {
                    link.apply(this, arguments); // apply this at the link phase
                    element.on('click', function(){ // when add an onclick that log hello when the directive is clicked.
                            console.log('hello!');
                    }); 
                };
            };
            return $delegate;
        });

    });

Se puede utilizar un enfoque similar tanto para los proveedores como para los servicios.

Directiva de herencia e interoperabilidad.

Las directivas angulares js se pueden anidar o hacer interoperables.

En este ejemplo, la directiva Adir expone a la directiva Bdir es su controlador $ scope, ya que Bdir requiere Adir.

angular.module('myApp',[]).directive('Adir', function () {
        return {
            restrict: 'AE',
            controller: ['$scope', function ($scope) {
                    $scope.logFn = function (val) {
                            console.log(val);
                        }
                  }]
            }
    })

Asegúrese de que los ajustes requieran: '^ Adir' (mire la documentación angular, algunas versiones no requieren ^ carácter).

.directive('Bdir', function () {
        return {
            restrict: 'AE',
            require: '^Adir', // Bdir require Adir
            link: function (scope, elem, attr, Parent) { 
            // Parent is Adir but can be an array of required directives.
                elem.on('click', function ($event) {
                    Parent.logFn("Hello!"); // will log "Hello! at parent dir scope
                    scope.$apply(); // apply to parent scope.
                });
            }
        }
    }]);

Puedes anidar tu directiva de esta manera:

<div a-dir><span b-dir></span></div>
<a-dir><b-dir></b-dir> </a-dir>

No es necesario que las directivas estén anidadas en su HTML.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow