Dyrektywy w Angularze są mechanizmem pozwalającym w prosty sposób tworzyć potężne mechanizmy, służące zarówno do definiowania zachowań, jak i manipulacji modelem DOM. Podczas procesu kompilacji dyrektywy są wyszukiwane w kodzie HTML i przetwarzane zgodnie ze zdefiniowaną w nich logiką. Angular JS umożliwia wprowadzenie czterech rodzajów własnych dyrektyw. Mogą one być umieszczane w:
- nazwach elementów
- klasach
- atrybutach
- komentarzach
Istnieje pewna konwencja, której należy przestrzegać: w kodzie html dyrektywy piszemy jako tzw. snake - names (to-jest-dyrektywa), natomiast w code behind w tzw. camel - case (toJestDyrektywa). Deklaracja dyrektyw w widoku może przebiegać w następujący sposób.
<!doctype html>
<html ng-app="directivesSample">
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script src="scripts/myscript.js"></script>
</head>
<body>
<div class="my-first-directive"> </div>
<my-second-directive></my-second-directive>
<div my-third-directive></div>
<!-- directive: my-fourth-directive exp -->
</body>
</html>
Aby AngularJS mógł odpowiednio zinterpretować dyrektywy zawarte w widoku, należy skonfigurować moduł aplikacji w code behind.
angular.module('directivesSample', []).
directive('myFirstDirective', function(){
return {
restrict : 'C',
template : "<div><button>First directive</button>"+
"<label>{{myAttribute}} </label>" +
"<label>{{literal}} </label>" +
"<label>{{text}}</label>" +
"</div>",
scope: {
myAttribute:'@myAttribute',
literal : '=literal'
},
controller : function($scope){
console.log('controller first... ');
$scope.text = "someText";
$scope.literal += ' modified';
console.log("=literal " + $scope.literal);
}
}
})
W obiekcie konfigurującym mamy do dyspozycji szereg właściwości i funkcji, które możemy modyfikować. Poniżej omówione zostały niektóre z nich:
Informacja na temat tego, gdzie została umieszczona dyrektywa
(C - w klasie,
M - w komentarzu,
A - w atrybucie,
E - jako osobny element).
Zawiera kod HTML, który zostaje doklejony na końcu ciała elementu z dyrektywą. Można użyć property templateUrl z podaną ścieżką do osobnego pliku html z szablonem.
Po ustawieniu na
true dyrektywa zostanie zastąpiona szablonem (wymagane dla dyrektyw w komentarzach). Domyślnie wartość false, przez co szablon jest wstawiany do wnętrza dyrektywy
true - tworzy nowy scope w obrębie dyrektywy, dziedziczy po parent scope
{} - nowy izolowany scope (brak bezpośredniego dostępu do properties z parent scope). Podczas tworzenia scope można pobierać atrybuty z elementu DOM na którym zastosowana jest dyrektywa (np.
'@myAttribute', oraz dworzyć dwukierunkowy binding do właściwości z parent scope (np. '=literal'). Poniżej przykład:
<body ng-controller="myController">
<div>{{literal}}</div>
<div class="my-first-directive" literal="literal" my-attribute="myAttr"></div>
</body>
function myController($scope){
console.log('creating outer Scope...');
$scope.literal = 'outerScope';
}
angular.module('directivesSample', []).
directive('myFirstDirective', function(){
return {
restrict : 'C',
template : "<div><button>First directive</button>"+
"<label>{{myAttribute}} </label>" +
"<label>{{literal}} </label>" +
"<label>{{text}}</label>" +
"</div>",
scope: {
myAttribute:'@myAttribute',
literal : '=literal'
},
controller : function($scope){
console.log('controller first... ');
$scope.text = "someText";
$scope.literal += ' modified';
console.log("=literal " + $scope.literal);
}
}
})
Wyliczany napis w pierwszym divie zostanie przez data binding zaktualizowany na "outerScope modified".
- compile: function compile(tElement, tAttrs, scope)
Funkcja wywoływana podczas procesu kompilacji, na tym etapie transformuje się drzewo DOM, np. klonuje elementy za pomocą ng-repeat. Rzadko stosowana.
- link: function(scope, element, attrs)
W tym miejscu następuje rejestracja event handlerów dla elementów modelu DOM.
link: function(scope, element, attrs) {
$(element).bind('click',function(){
alert('click');
})
}