Sök…


Introduktion

Här kommer du att lära dig om direktivfunktionen i AngularJS. Nedan hittar du information om vad direktiv är, samt grundläggande och avancerade exempel på hur du använder dem.

parametrar

Parameter detaljer
omfattning Egendom för att ange tillämpningsområdet för direktivet. Det kan ställas in som falskt, sant eller som ett isolerat omfång: {@, =, <, &}.
omfattning: förfalskning Direktivet använder föräldrarnas tillämpningsområde. Inget utrymme skapas för direktiv.
omfattning: sant Direktivet ärver föräldrars räckvidd prototypiskt som ett nytt barnomfång. Om det finns flera direktiv om samma element som begär ett nytt tillämpningsområde, kommer de att dela ett nytt tillämpningsområde.
omfattning: {@} Ett sätt att binda en egenskap för direktivomfång till ett DOM-attributvärde. Eftersom attributvärdet är bundet i föräldern kommer det att ändras i direktivets omfattning.
omfattning: {=} Dubbelriktad attributbindning som ändrar attributet i föräldern om direktivattributet ändras och vice versa.
omfattning: {<} Envägsbindning av ett direktivs omfattningsegenskap och ett DOM-attribututtryck. Uttrycket utvärderas hos föräldern. Detta tittar på överordnadsvärdets identitet så att ändringar av en objektegenskap i föräldern inte kommer att återspeglas i direktivet. Ändringar av en objektegenskap i ett direktiv kommer att återspeglas i överordnade eftersom båda refererar till samma objekt
omfattning: {&} Tillåter direktivet att överföra data till ett uttryck som ska utvärderas i föräldern.
kompilera: funktion Denna funktion används för att utföra DOM-transformation på direktivmallen innan länkfunktionen körs. Den accepterar tElement (direktivsmallen) och tAttr (lista över attribut som deklarerats i direktivet). Den har inte tillgång till omfattningen. Det kan returnera en funktion som kommer att registreras som en post-link funktion eller så kan den returnera ett objekt med pre och post egenskaper med kommer att registreras som pre-link och post-link funktioner.
länk: funktion / objekt Länkegenskapen kan konfigureras som en funktion eller ett objekt. Den kan ta emot följande argument: omfattning (direktivomfång), iElement (DOM-element där direktivet tillämpas), iAttrs (samling av DOM-elementattribut), controller (array av styrenheter som krävs enligt direktiv), transcludeFn. Det används främst för att ställa in DOM-lyssnare, titta på modellegenskaper för ändringar och uppdatera DOM. Den körs efter att mallen klonats. Det konfigureras oberoende om det inte finns någon kompilationsfunktion.
förlänksfunktion Länkfunktion som körs innan någon länkfunktion fungerar. Som standard exekverar länkfunktioner för barndirektiv före förälderdirektivets länkfunktioner och förlänkfunktionen gör det möjligt för föräldern att länka först. Ett användningsfall är om barnet behöver data från föräldern.
post-länk funktion Länkfunktion som verkställande efter barnelement är länkad till förälder. Det används ofta för att ansluta händelseshanterare och få åtkomst till barndirektiv, men data som krävs enligt barndirektivet bör inte anges här eftersom barndirektivet redan har kopplats till.
begränsa: sträng Definierar hur man kallar direktivet från DOM. Möjliga värden (förutsatt att vårt direktivnamn är demoDirective ): E - Elementnamn ( <demo-directive></demo-directive> ), A - Attribut ( <div demo-directive></div> ), C - Matchningsklass ( <div class="demo-directive"></div> ), M - Med kommentar ( <!-- directive: demo-directive --> ). restrict kan också stödja flera alternativ, till exempel - restrict: "AC" kommer att begränsa direktivet till attribut ELLER klass . Om utelämnas är standardvärdet "EA" (Element eller attribut).
kräver: 'demoDirective' Leta reda på demoDirective's controller på det aktuella elementet och injicera sin controller som det fjärde argumentet till länkningsfunktionen. Kasta ett fel om det inte hittas.
kräver: '? demoDirective' Försök att hitta demoDirective's controller eller skicka noll till länken fn om den inte hittas.
kräver: '^ demoDirective' Leta reda på demoDirective's controller genom att söka efter elementet och dess föräldrar. Kasta ett fel om det inte hittas.
kräver: '^^ demoDirective' Leta upp demoDirective-kontrollern genom att söka efter elementets föräldrar. Kasta ett fel om det inte hittas.
kräver: '? ^ demoDirective' Försök att hitta demoDirective-kontrollern genom att söka efter elementet och dess föräldrar eller skicka noll till länken fn om den inte hittas.
kräver: '? ^^ demoDirective' Försök att hitta demoDirective's controller genom att söka efter elementets föräldrar, eller skicka noll till länken fn om den inte hittas.

Skapa och konsumera anpassade direktiv

Direktiv är en av de mest kraftfulla funktionerna hos angularjs. Anpassade angularjs-direktiv används för att utöka funktionaliteten för html genom att skapa nya html-element eller anpassade attribut för att ge ett beteende till en html-tagg.

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

Detta direktiv kan sedan användas i App som:

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

Direktiv Definition Objektmall

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 - inställt på true och alla DOM-noder mellan start och slut på direktivnamnet kommer att samlas in och grupperas som direktivelement
  2. priority - tillåter specifikation av beställningen för att tillämpa direktiv när flera direktiv definieras på ett enda DOM-element. Direktiv med högre antal sammanställs först.
  3. terminal - inställt på true och den aktuella prioriteringen är den sista uppsättningen av direktiv som ska genomföras
  4. scope - anger direktivets räckvidd
  5. bind to controller - binder omfattningsegenskaper direkt till direktivkontrollen
  6. controller - controllerkonstruktorfunktion
  7. require - kräva ett annat direktiv och injicera sin controller som det fjärde argumentet till länkfunktionen
  8. controllerAs - namnreferens till regulatorn i direktivets omfattning för att tillåta att referensen refereras från direktivmallen.
  9. restrict - begränsa direktivet till Element, attribut, klass eller kommentar
  10. templateNameSpace - anger dokumenttyp som används av direktivmallen: html, svg eller math. html är standard
  11. template - html-markering som standard ersätter innehållet i direktivets element, eller lindar innehållet i direktivet om transclude är sant
  12. templateUrl - url tillhandahålls asynkront för mallen
  13. transclude - extrahera innehållet i elementet där direktivet visas och gör det tillgängligt för direktivet. Innehållet sammanställs och tillhandahålls till direktivet som en transkluderingsfunktion.
  14. compile - funktion för att transformera mallen DOM
  15. link - används endast om kompileraegenskapen inte är definierad. Länkfunktionen ansvarar för att registrera DOM-lyssnare samt uppdatera DOM. Det körs efter att mallen har klonats.

Exempel på grundläggande direktiv

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

Du kan kolla mer om direktivets restrict och link AngularJS: s officiella dokumentation om direktiv

Hur man skapar resuable-komponent med direktiv

AngularJS-direktiv är det som styr återgivningen av HTML i en AngularJS-applikation. De kan vara ett Html-element, attribut, klass eller en kommentar. Direktiv används för att manipulera DOM, koppla nytt beteende till HTML-element, databindning och många fler. Några av exempel på riktlinjer som vinklas tillhandahåller är ng-model, ng-hud, ng-if.

På liknande sätt kan man skapa sitt eget anpassade direktiv och göra dem omsläppliga. För att skapa anpassade direktiv Referens . Känslan bakom att skapa återanvändbara direktiv är att skapa en uppsättning av direktiv / komponenter skrivna av dig precis som angularjs ger oss med hjälp av angular.js. Dessa återanvändbara direktiv kan vara särskilt användbara när du har svit med applikationer / applikationer som kräver ett konsekvent beteende, utseende och känsla. Ett exempel på en sådan återanvändbar komponent kan vara ett enkelt verktygsfält som du kanske vill använda över hela din applikation eller olika applikationer men du vill att de ska uppträda på samma sätt eller se samma ut.

Först skapar du en mapp som heter resuableComponents i din app-mapp och gör 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>

Direktivet är återanvändbara komponenter som standard. När du skapar direktiv i en separat vinkelmodul gör den den faktiskt exporterbar och återanvändbar över olika vinklade J-applikationer. Nya direktiv kan helt enkelt läggas till i reusableModuleApp.js och reusableModuleApp kan ha sin egen controller, tjänster, DDO-objekt i direktivet för att definiera beteendet.

Grunddirektiv med mall och en isolerad räckvidd

Att skapa ett anpassat direktiv med isolerat tillämpningsområde kommer att separera räckvidden inuti direktivet från det yttre tillämpningsområdet, för att förhindra att vårt direktiv av misstag ändrar uppgifterna i överordnade omfång och begränsar det från att läsa privata uppgifter från överordnade omfång.

För att skapa ett isolerat tillämpningsområde och fortfarande låta vårt anpassade direktiv kommunicera med det yttre räckvidden, kan vi använda scope som beskriver hur man kartlägger bindningarna i direktivets inre räckvidd med det yttre räckvidden.

De faktiska bindningarna är gjorda med extra attribut knutna till direktivet. Bindningsinställningarna definieras med scope och ett objekt med nyckelvärdespar:

  • En nyckel , som motsvarar vårt direktivs isolerade omfattningsegendom
  • Ett värde , som berättar för Angular hur binder direktivets inre räckvidd till ett matchande attribut

Enkelt exempel på ett direktiv med isolerat tillämpningsområde:

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

Exempel på hur man använder detta direktiv och binder data från controllerens omfattning till direktivets inre räckvidd:

Kontrollant:

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

Se:

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

Bygga en återanvändbar komponent

Direktiv kan användas för att bygga återanvändbara komponenter. Här är ett exempel på en "användarbox" -komponent:

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>

användar box.html

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

Resultatet blir:

John Doe
1250 reputation
Andrew
2850 reputation

Direktdekoratör

Ibland kan du behöva ytterligare funktioner från ett direktiv. Istället för att skriva om (kopiera) direktivet kan du ändra hur direktivet beter sig.

Dekoratören kommer att köras under $ injektionsfasen.

För att göra det, provde en .konfig till din modul. Direktivet kallas myDirective, så du måste konfigurera myDirectiveDirective. (detta i en vinklad konvention [läs om leverantörer]).

Detta exempel kommer att ändra mallenUrl för direktivet:

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

I det här exemplet läggs en onClick-händelse till direktivelementet när det klickas, detta händer under kompileringsfasen.

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

    });

Liknande tillvägagångssätt kan användas för både leverantörer och tjänster.

Direktiv arv och interoperabilitet

Vinklade js-direktiv kan kapslas eller göras driftskompatibla.

I det här exemplet exponerar direktiv Adir för direktiv Bdir dess controller $ scope, eftersom Bdir kräver Adir.

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

Se till att ställa krav: '^ Adir' (titta på vinkeldokumentationen, vissa versioner kräver inte ^ -tecken).

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

Du kan bo ditt direktiv på detta sätt:

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

Krävs inte att direktiv kapslas i din HTML.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow