Pour nommer des directives personnalisées dans AngularJS, il est recommandé d'utiliser le format [espace-nom-nom-directive], comme ng-controller. Toutefois, évitez le préfixe ng- pour prévenir les conflits avec les directives intégrées. Les directives sont définies en camelCase et appliquées avec des tirets ; par exemple, une directive définie sous le nom maDirective s'utilise comme <ma-directive>.
Voici des exemples de noms de directives valides :
- ng:bind
- ng-bind
- ng_bind
- x-ng-bind
- data-ng-bind
Dans un contexte éducatif, pour valider une saisie de note entre 1 et 10, on peut créer une directive personnalisée. Voici une implémentation qui applique une bordure rouge en cas de valeur invalide :
app.directive('validateurNote', function() {
return {
link: function(scope, el, attrs, ctrl) {
el[0].addEventListener('keyup', function() {
var valeur = parseFloat(this.value);
if (isNaN(valeur) || valeur < 1 || valeur > 10) {
this.style.borderColor = 'red';
} else {
this.style.borderColor = '';
}
});
}
};
});
Utilisation dans un template :
Note : <input type="text" ng-model="question.note" validateur-note /><br />
Explorons maintenant les différences entre controller, link et compile dans une directive. Considérons l'exemple suivant :
app.directive('demoDirective', function() {
return {
restrict: 'E',
template: '<p>Score : {{score}}</p>',
controller: function($scope, $element) {
$scope.score = $scope.score + "22222 ";
},
link: function(scope, el, attr) {
scope.score = scope.score + "33333 ";
},
compile: function(element, attributes) {
return {
pre: function(scope, element, attributes) {
scope.score = scope.score + "44444 ";
},
post: function(scope, element, attributes) {
scope.score = scope.score + "55555 ";
}
};
}
};
});
app.controller('DemoCtrl', ['$scope', function($scope) {
$scope.score = '1111 ';
}]);
<body ng-app="myApp">
<div ng-controller="DemoCtrl">
<demo-directive></demo-directive>
</div>
</body>
Le résultat affiché est : Score : 1111 22222 44444 55555 !. Cela montre que le controller s'exécute en premier, suivi du compile avec ses fonctions pre et post. Notez que le link n'est pas appelé ici, car il est équivalent au post de compile.
Si l'on commente la partie compile :
app.directive('demoDirective', function() {
return {
restrict: 'E',
template: '<p>Score : {{score}}</p>',
controller: function($scope, $element) {
$scope.score = $scope.score + "22222 ";
},
link: function(scope, el, attr) {
scope.score = scope.score + "33333 ";
}
};
});
Le résultat devient : Score : 1111 22222 33333 !. Ainsi, sans compile, le controller s'exécute avant le link. En pratique, compile est utilisé pour des transformations de DOM, tandis que link gère la logique événementielle et le comportement. Ces deux fonctions ne sont pas compatibles en même temps lorsqu'elles modifient le même état.