Szukaj…


Wprowadzenie

Tutaj dowiesz się o funkcji dyrektyw w AngularJS. Poniżej znajdziesz informacje o tym, czym są dyrektywy, a także podstawowe i zaawansowane przykłady ich stosowania.

Parametry

Parametr Detale
zakres Właściwość, aby ustawić zakres dyrektywy. Może być ustawiony jako false, true lub jako izolowany zakres: {@, =, <i}.
zakres: fałsz Dyrektywa wykorzystuje zakres nadrzędny. Nie utworzono zakresu dla dyrektywy.
zakres: prawda Dyrektywa dziedziczy prototypowo zakres nadrzędny jako nowy zakres potomny. Jeśli istnieje wiele dyrektyw dotyczących tego samego elementu, które żądają nowego zakresu, będą one dzielić jeden nowy zakres.
zakres: {@} Jednokierunkowe wiązanie właściwości zakresu dyrektywy z wartością atrybutu DOM. Jako wartość atrybutu związana w obiekcie nadrzędnym zmieni się ona w zakresie dyrektywy.
zakres: {=} Dwukierunkowe wiązanie atrybutów, które zmienia atrybut w elemencie nadrzędnym, jeśli atrybut dyrektywy ulegnie zmianie i odwrotnie.
zakres: {<} Powiązanie w jedną stronę właściwości zakresu dyrektywy i wyrażenia atrybutu DOM. Wyrażenie jest oceniane w obiekcie nadrzędnym. Obserwuje to tożsamość wartości nadrzędnej, więc zmiany właściwości obiektu w obiekcie nadrzędnym nie zostaną odzwierciedlone w dyrektywie. Zmiany właściwości obiektu w dyrektywie zostaną odzwierciedlone w obiekcie nadrzędnym, ponieważ oba odnoszą się do tego samego obiektu
zakres: {i} Pozwala dyrektywie przekazywać dane do wyrażenia, które ma zostać ocenione w obiekcie nadrzędnym.
kompilacja: funkcja Ta funkcja służy do przeprowadzania transformacji DOM na szablonie dyrektywy przed uruchomieniem funkcji link. Akceptuje tElement (szablon dyrektywy) i tAttr (lista atrybutów zadeklarowanych w dyrektywie). Nie ma dostępu do zakresu. Może zwrócić funkcję, która zostanie zarejestrowana jako funkcja post-link lub może zwrócić obiekt z właściwościami pre i post z, które zostaną zarejestrowane jako funkcje pre-link i post-link .
link: funkcja / obiekt Właściwość link można skonfigurować jako funkcję lub obiekt. Może otrzymywać następujące argumenty: zakres (zakres dyrektywy), iElement (element DOM, w którym stosowana jest dyrektywa), iAttrs (zbiór atrybutów elementu DOM), kontroler (tablica kontrolerów wymagana przez dyrektywę), transcludeFn. Służy głównie do konfigurowania detektorów DOM, oglądania właściwości modelu pod kątem zmian i aktualizowania DOM. Wykonuje się po sklonowaniu szablonu. Jest konfigurowany niezależnie, jeśli nie ma funkcji kompilacji.
funkcja wstępnego linkowania Funkcja łącza, która jest wykonywana przed dowolnymi funkcjami połączenia potomnego. Domyślnie funkcje łącza dyrektywy podrzędnej są wykonywane przed funkcjami połączenia dyrektywy nadrzędnej, a funkcja połączenia wstępnego umożliwia najpierw połączenie elementu nadrzędnego. Jednym z przypadków użycia jest sytuacja, gdy dziecko potrzebuje danych od rodzica.
funkcja post-link Funkcja łączenia, która wykonuje się po połączeniu elementów potomnych z rodzicem. Jest powszechnie używany do dołączania procedur obsługi zdarzeń i uzyskiwania dostępu do dyrektyw podrzędnych, ale nie należy tu ustawiać danych wymaganych przez dyrektywę podrzędną, ponieważ dyrektywa podrzędna zostanie już połączona.
ogranicz: ciąg Określa, jak wywołać dyrektywę z poziomu DOM. Możliwe wartości (Zakładając, że nazwą naszej dyrektywy jest demoDirective ): E - Nazwa elementu ( <demo-directive></demo-directive> ), A - Atrybut ( <div demo-directive></div> ), C - Pasująca klasa ( <div class="demo-directive"></div> ), M - Przez komentarz ( <!-- directive: demo-directive --> ). Właściwość restrict może także obsługiwać wiele opcji, na przykład - restrict: "AC" ograniczy dyrektywę do atrybutu LUB klasy . Jeśli zostanie pominięty, wartością domyślną jest "EA" (Element lub Atrybut).
wymagają: „demoDirective” Zlokalizuj kontroler demoDirective na bieżącym elemencie i wstrzyknij jego kontroler jako czwarty argument funkcji łączącej. Zgłaszaj błąd, jeśli nie został znaleziony.
wymagają: „? demoDirective” Spróbuj zlokalizować kontroler demoDirective lub przekaż null do linku fn, jeśli nie zostanie znaleziony.
wymagają: „^ demoDirective” Zlokalizuj kontroler demoDirective, przeszukując element i jego rodziców. Zgłaszaj błąd, jeśli nie został znaleziony.
wymagają: „^^ demoDirective” Znajdź kontroler demoDirective, przeszukując rodziców elementu. Zgłaszaj błąd, jeśli nie został znaleziony.
wymagają: „? ^ demoDirective” Próba zlokalizowania kontrolera demoDirective poprzez przeszukanie elementu i jego rodziców lub przekazanie null do linku fn, jeśli nie zostanie znaleziony.
wymagają: „? ^^ demoDirective” Spróbuj zlokalizować kontroler demoDirective, przeszukując rodziców elementu lub przekaż null do linku fn, jeśli nie zostanie znaleziony.

Tworzenie i używanie niestandardowych dyrektyw

Dyrektywy są jedną z najpotężniejszych cech angularjs. Niestandardowe dyrektywy angularjs służą do rozszerzania funkcjonalności HTML poprzez tworzenie nowych elementów HTML lub niestandardowych atrybutów w celu zapewnienia określonego zachowania znacznikowi HTML.

dyrektywa.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;
    }
  };
});

Tę dyrektywę można następnie wykorzystać w aplikacji jako:

<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>

Szablon obiektu definicji dyrektywy

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 - ustawiona na true, a wszystkie węzły DOM między początkiem a końcem nazwy dyrektywy zostaną zebrane i zgrupowane razem jako elementy dyrektywy
  2. priority - pozwala na określenie kolejności stosowania dyrektyw, gdy w jednym elemencie DOM zdefiniowano wiele dyrektyw. Dyrektywy o wyższych liczbach są kompilowane w pierwszej kolejności.
  3. terminal - ustawiony na true, a bieżącym priorytetem będzie ostatni zestaw dyrektyw do wykonania
  4. scope - określa zakres dyrektywy
  5. bind to controller - wiąże właściwości zakresu bezpośrednio z kontrolerem dyrektywy
  6. controller - funkcja konstruktora kontrolera
  7. require - wymaga innej dyrektywy i wstrzykuje kontroler jako czwarty argument funkcji łączącej
  8. controllerAs - odwołanie do nazwy kontrolera w zakresie dyrektywy, aby umożliwić odwołanie do kontrolera z szablonu dyrektywy.
  9. restrict - ogranicza dyrektywę do elementu, atrybutu, klasy lub komentarza
  10. templateNameSpace - ustawia typ dokumentu używany przez szablon dyrektywy: html, svg lub matematyki. HTML jest domyślny
  11. template - znaczniki html, które domyślnie zastępują treść elementu dyrektywy lub zawijają zawartość elementu dyrektywy, jeśli prawdą jest transclude
  12. templateUrl - adres URL podany asynchronicznie dla szablonu
  13. transclude - Wyodrębnij zawartość elementu, w którym pojawia się dyrektywa i udostępnij ją dyrektywie. Treści są kompilowane i dostarczane do dyrektywy jako funkcja transkluzji.
  14. compile - funkcja przekształcająca szablon DOM
  15. link - używany tylko wtedy, gdy właściwość kompilacji nie jest zdefiniowana. Funkcja link odpowiada za rejestrację detektorów DOM oraz aktualizację DOM. Jest wykonywany po sklonowaniu szablonu.

Przykład podstawowej dyrektywy

superman-policy.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>

Możesz dowiedzieć się więcej na temat funkcji restrict i link dyrektywy w oficjalnej dokumentacji AngularJS na temat dyrektyw

Jak utworzyć komponent podlegający wymianie przy użyciu dyrektywy

Dyrektywy AngularJS kontrolują renderowanie HTML w aplikacji AngularJS. Mogą to być element HTML, atrybut, klasa lub komentarz. Dyrektywy służą do manipulowania DOM, dołączania nowego zachowania do elementów HTML, wiązania danych i wielu innych. Niektóre przykłady dyrektyw, które zapewnia kąt, to ng-model, ng-hide, ng-if.

Podobnie można stworzyć własną niestandardową dyrektywę i uczynić ją możliwą do ponownego wykorzystania. Do tworzenia niestandardowych dyrektyw Odniesienia . Sens tworzenia dyrektyw wielokrotnego użytku polega na tworzeniu zestawu dyrektyw / komponentów napisanych przez ciebie, tak jak angularjs zapewnia nam angular.js. Te dyrektywy wielokrotnego użytku mogą być szczególnie pomocne, gdy masz pakiet aplikacji / aplikacji, które wymagają spójnego zachowania, wyglądu i działania. Przykładem takiego komponentu wielokrotnego użytku może być prosty pasek narzędzi, którego możesz chcieć używać w swojej aplikacji lub różnych aplikacjach, ale chcesz, aby zachowywały się tak samo lub wyglądały tak samo.

Po pierwsze, utwórz folder o nazwie resuableComponents w folderze aplikacji i utwórz plik reusableModuleApp.js

reusableModuleApp.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>

Dyrektywa jest domyślnie składnikami wielokrotnego użytku. Kiedy tworzysz dyrektywy w oddzielnym module kątowym, w rzeczywistości sprawia, że można je eksportować i wykorzystywać w różnych aplikacjach angularJs. Nowe dyrektywy można po prostu dodać do reusableModuleApp.js, a reusableModuleApp może mieć własny kontroler, usługi, obiekt DDO wewnątrz dyrektywy, aby zdefiniować zachowanie.

Podstawowa dyrektywa z szablonem i izolowanym zakresem

Utworzenie niestandardowej dyrektywy z izolowanym zakresem oddzieli zakres wewnątrz dyrektywy od zakresu zewnętrznego , aby zapobiec przypadkowej zmianie danych w zakresie nadrzędnym przez naszą dyrektywę i ograniczyć odczytywanie danych prywatnych z zakresu nadrzędnego.

Aby utworzyć izolowany zakres i nadal pozwalać naszej niestandardowej dyrektywie komunikować się z zakresem zewnętrznym, możemy użyć opcji scope , która opisuje, w jaki sposób mapować powiązania wewnętrznego zakresu dyrektywy z zakresem zewnętrznym.

Rzeczywiste powiązania są tworzone za pomocą dodatkowych atrybutów dołączonych do dyrektywy. Ustawienia powiązania są definiowane za pomocą opcji scope i obiektu z parami klucz-wartość:

  • Klucz , który odpowiada izolowanej własności zakresu naszej dyrektywy
  • Wartość , która mówi Angularowi, jak powiązać wewnętrzny zasięg dyrektywy z pasującym atrybutem

Prosty przykład dyrektywy z izolowanym zakresem:

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);

Przykład zastosowania tej dyrektywy i powiązania danych z zakresu kontrolera z wewnętrznym zakresem dyrektywy:

Kontroler:

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

Widok:

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

Budowanie komponentu wielokrotnego użytku

Dyrektywy mogą być wykorzystane do budowy komponentów wielokrotnego użytku. Oto przykład elementu „skrzynki użytkownika”:

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>

Wynik będzie:

John Doe
1250 reputation
Andrew
2850 reputation

Dekorator dyrektywy

Czasami możesz potrzebować dodatkowych funkcji z dyrektywy. Zamiast przepisywać (kopiować) dyrektywę, możesz zmodyfikować jej zachowanie.

Dekorator zostanie wykonany podczas fazy wprowadzania.

Aby to zrobić, sprawdź .config w swoim module. Dyrektywa nazywa się myDirective, więc musisz skonfigurować myDirectiveDirective. (to w konwencji kątowej [czytaj o dostawcach]).

Ten przykład zmieni szablon templateUrl dyrektywy:

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;
    })
});

Ten przykład dodaje zdarzenie onClick do elementu dyrektywy po kliknięciu, dzieje się to podczas fazy kompilacji.

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;
        });

    });

Podobne podejście można zastosować zarówno dla dostawców, jak i usług.

Dziedziczenie dyrektywy i interoperacyjność

Dyrektywy kątowe js mogą być zagnieżdżone lub być interoperacyjne.

W tym przykładzie dyrektywa Adir udostępnia dyrektywę Bdir jej zakres kontrolera $, ponieważ Bdir wymaga Adira.

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

Pamiętaj, aby ustawić wymaganie: '^ Adir' (spójrz na dokumentację kątową, niektóre wersje nie wymagają ^ znaku).

.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.
                });
            }
        }
    }]);

Możesz zagnieździć swoją dyrektywę w następujący sposób:

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

Nie jest wymagane, aby dyrektywy były zagnieżdżone w kodzie HTML.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow