Différences
Ci-dessous, les différences entre deux révisions de la page.
slam4:richclient:angularjs:directives [2015/01/06 19:38] – [Link/compile] jcheron | slam4:richclient:angularjs:directives [2019/08/31 14:21] (Version actuelle) – modification externe 127.0.0.1 | ||
---|---|---|---|
Ligne 44: | Ligne 44: | ||
|**[[https:// | |**[[https:// | ||
|**[[https:// | |**[[https:// | ||
- | |**[[https:// | + | |**[[https:// |
- | + | |**[[https://docs.angularjs.org/api/ng/directive/ngClass|ng-class]]** | | |
- | ng-click, ng-show, | + | |**[[https://docs.angularjs.org/api/ng/directive/ngSubmit|ng-submit]]** | |
- | ng-submit | + | |
- | + | ||
- | ===== Création de directives ===== | + | |
- | Quels intérêts ? | + | |
- | + | ||
- | | + | |
- | | + | |
- | + | ||
- | + | ||
- | ==== Directive simple & template ==== | + | |
- | + | ||
- | <sxh javascript; | + | |
- | var app = angular.module(' | + | |
- | .controller(' | + | |
- | $scope.client = { | + | |
- | nom: ' | + | |
- | prenom: ' | + | |
- | }; | + | |
- | }]); | + | |
- | + | ||
- | app.directive(' | + | |
- | return { | + | |
- | template: 'Nom : {{client.nom}} Prénom : {{client.prenom}}' | + | |
- | }; | + | |
- | }); | + | |
- | </sxh> | + | |
- | + | ||
- | **Utilisations possibles :** | + | |
- | + | ||
- | <sxh html; | + | |
- | <html data-ng-app=" | + | |
- | ... | + | |
- | < | + | |
- | <div my-client></ | + | |
- | </ | + | |
- | + | ||
- | **Résultat :** | + | |
- | + | ||
- | {{: | + | |
- | + | ||
- | ==== templateUrl ==== | + | |
- | Excepté pour les petits templates, il est préférable d' | + | |
- | <sxh javascript; | + | |
- | app.directive(' | + | |
- | return { | + | |
- | templateUrl: | + | |
- | }; | + | |
- | }); | + | |
- | </sxh> | + | |
- | + | ||
- | <sxh html; | + | |
- | Nom : {{client.nom}} Prénom : {{client.prenom}} | + | |
- | </sxh> | + | |
- | + | ||
- | La propriété templateUrl peut-être définie par une fonction : | + | |
- | + | ||
- | <sxh javascript; | + | |
- | app.directive(' | + | |
- | return { | + | |
- | templateUrl: | + | |
- | return ' | + | |
- | } | + | |
- | }; | + | |
- | }); | + | |
- | </sxh> | + | |
- | + | ||
- | **Templates :** | + | |
- | <sxh html; | + | |
- | Nom : {{client.nom}} Prénom : {{client.prenom}} | + | |
- | </ | + | |
- | + | ||
- | <sxh html; | + | |
- | Adresse: {{client.adresse}}< | + | |
- | CP: {{client.cp}} {{client.ville}} | + | |
- | </ | + | |
- | + | ||
- | **Utilisation :** | + | |
- | <sxh html; | + | |
- | <html data-ng-app=" | + | |
- | ... | + | |
- | <div myclient type=" | + | |
- | <div my-client type=" | + | |
- | </ | + | |
- | ==== restrict ==== | + | |
- | La propriété | + | |
- | * éléments - **E** | + | |
- | * attributs - **A** | + | |
- | * classe Css - **C** | + | |
- | * commentaire - **M** | + | |
- | * ou une combinaison de ces valeurs : **EA** par exemple, pour élément et attribut | + | |
- | + | ||
- | Si la directive est définie sur 1 élément : | + | |
- | < | + | |
- | app.directive(' | + | |
- | return { | + | |
- | restrict: ' | + | |
- | templateUrl: | + | |
- | return ' | + | |
- | } | + | |
- | }; | + | |
- | }); | + | |
- | </ | + | |
- | + | ||
- | Seule la première ligne sera compilée par Angular, la seconde sera ignorée | + | |
- | <sxh html; | + | |
- | <html data-ng-app="testDirectivesApp" | + | |
- | ... | + | |
- | < | + | |
- | <div my-client type=" | + | |
- | </ | + | |
- | + | ||
- | ==== scope ==== | + | |
- | Le scope défini la portée d'une directive. Sans précision, le scope d'une directive est le scope de son contrôleur parent. Ce qui explique que notre directive ait pu accéder à la variable **client** | + | |
- | + | ||
- | === Isolation === | + | |
- | La directive précédemment créée a un défaut : elle dépend du contrôleur dans laquelle elle a été définie, et si nous souhaitons afficher un autre client, il faut définir un autre contrôleur...\\ | + | |
- | La définition de la variable scope de la directive permet de résoudre ce problème : | + | |
- | + | ||
- | + | ||
- | **scope:{}** | + | |
- | Défini à {}, la directive a un scope qui lui est propre, différent de celui du controller auquel elle appartient : | + | |
- | <sxh javascript; | + | |
- | app.directive(' | + | |
- | return { | + | |
- | restrict: ' | + | |
- | scope:{}, | + | |
- | templateUrl: | + | |
- | return ' | + | |
- | } | + | |
- | }; | + | |
- | }); | + | |
- | </sxh> | + | |
- | + | ||
- | Avec ce scope isolé, la directive ne peut plus accéder à la variable client définie dans le scope du controller : tester la page tests.html | + | |
- | + | ||
- | Nous allons ajouter une propriété permettant d' | + | |
- | + | ||
- | <sxh html; | + | |
- | <html data-ng-app=" | + | |
- | ... | + | |
- | < | + | |
- | < | + | |
- | </sxh> | + | |
- | + | ||
- | <sxh javascript; | + | |
- | app.directive(' | + | |
- | return{ | + | |
- | restrict:' | + | |
- | scope: | + | |
- | templateUrl: | + | |
- | return ' | + | |
- | } | + | |
- | } | + | |
- | }); | + | |
- | </sxh> | + | |
- | + | ||
- | L' | + | |
- | + | ||
- | Lorsqu' | + | |
- | <sxh javascript; | + | |
- | scope : {attributeName: | + | |
- | </ | + | |
- | + | ||
- | Pour résumer (rapidement...) : | + | |
- | + | ||
- | ^Valeurs de scope ^Résultats ^ | + | |
- | | false ou non définie | + | |
- | | {} | scope isolé | | + | |
- | | {attributeName:" | + | |
- | | {attributeNameInDirectiveScope:" | + | |
- | | {attributeName:" | + | |
- | | {attributeNameInDirectiveScope:" | + | |
- | | {attributeName:"&" | + | |
- | | {attributeNameInDirectiveScope:"& | + | |
- | | true | scope non isolé | | + | |
- | + | ||
- | **Exemple de passage d'une expression action (ng-click) :** | + | |
- | <sxh html;title: | + | |
- | < | + | |
- | <div my-client type=" | + | |
- | </ | + | |
- | + | ||
- | Sur click du nom, l' | + | |
- | + | ||
- | En l' | + | |
- | <sxh javascript; | + | |
- | app.directive(' | + | |
- | return{ | + | |
- | restrict:' | + | |
- | scope: | + | |
- | templateUrl: | + | |
- | return ' | + | |
- | } | + | |
- | } | + | |
- | }); | + | |
- | </ | + | |
- | + | ||
- | et la déclencher à nouveau dans le template : | + | |
- | <sxh html; | + | |
- | <p ng-click=" | + | |
- | </ | + | |
- | + | ||
- | ==== Link/ | + | |
- | Lorsqu' | + | |
- | - compile | + | |
- | - controller | + | |
- | - pre-link | + | |
- | - post-link | + | |
- | Si une directive doit modifier ou créer le DOM d'un template défini dans une directive, elle doit donc définir certaines de ces fonctions. | + | |
- | + | ||
- | === fonction compile === | + | |
- | <sxh javascript:gutter: | + | |
- | compile : function(tElement, | + | |
- | + | ||
- | } | + | |
- | </sxh> | + | |
- | Utilisée pour la manipulation du DOM (manipulation de tElement = template element), elle permet des manipulations qui s' | + | |
- | S'il est nécessaire de définir également la fonction link (ou pre ou post link), et que la fonction compile est définie, la fonction compile doit renvoyer le(s) fonction(s) link, étant donné que link est ignoré si compile existe. | + | |
- | + | ||
- | === fonction controller === | + | |
- | <sxh javascript: | + | |
- | controller : function($scope, | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | Elle doit être utilisée pour permettre l' | + | |
- | + | ||
- | === fonction link === | + | |
- | <sxh javascript: | + | |
- | link : function(scope, | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | Elle est habituellement utilisée pour enregistrer des listeners DOM (i.e., $watch expressions sur le scope) ou pour mettre à jour le DOM (i.e., manipulation sur iElement = instance individuelle de element). Elle est exécutée après que le template ait été cloné -- voir < | + | |
- | + | ||
- | + | ||
- | === Exemple === | + | |
- | + | ||
- | Soit la directive SoldeDir, dont les fonctionnalités sont les suivantes : | + | |
- | * Affichage d'une valeur numérique (attribut montant), éventuellement en gras (attribut bold) | + | |
- | * Si le montant est positif, il est affiché en <fc # | + | |
- | * S'il est négatif, en <fc # | + | |
- | + | ||
- | <sxh javascript; | + | |
- | app.directive(' | + | |
- | return { | + | |
- | restrict : ' | + | |
- | scope: | + | |
- | compile : function(tElem, tAttrs) { | + | |
- | if (tAttrs.bold == "true" | + | |
- | tElem.css(" | + | |
- | else | + | |
- | tElem.css(" | + | |
- | var linkFunction = function($scope, | + | |
- | var update=function(){ | + | |
- | if($scope.montant< | + | |
- | tElem.html(" | + | |
- | tElem.css(" | + | |
- | }else{ | + | |
- | tElem.html($scope.montant); | + | |
- | tElem.css(" | + | |
- | } | + | |
- | } | + | |
- | update(); | + | |
- | } | + | |
- | return linkFunction; | + | |
- | } | + | |
- | } | + | |
- | }); | + | |
- | </sxh> | + | |
- | + | ||
- | + | ||
- | <sxh html; | + | |
- | <div ng-init=" | + | |
- | <input type=" | + | |
- | < | + | |
- | </ | + | |
- | + | ||
- | {{: | + | |
- | + | ||
- | La directive fonctionne pour l' | + | |
- | Pour remédier à ce problème, il faut ajouter dans la fonction link un appel au service **$watch**, pour observer et reporter les modifications du montant : | + | |
- | + | ||
- | <sxh javascript; | + | |
- | app.directive(' | + | |
- | return { | + | |
- | restrict : ' | + | |
- | scope: | + | |
- | compile : function(tElem, | + | |
- | if (tAttrs.bold == " | + | |
- | tElem.css(" | + | |
- | else | + | |
- | tElem.css(" | + | |
- | var linkFunction = function($scope, | + | |
- | var update=function(){ | + | |
- | if($scope.montant< | + | |
- | tElem.html(" | + | |
- | tElem.css(" | + | |
- | }else{ | + | |
- | tElem.html($scope.montant); | + | |
- | tElem.css(" | + | |
- | } | + | |
- | } | + | |
- | update(); | + | |
- | } | + | |
- | $scope.$watch(' | + | |
- | update(); | + | |
- | }); | + | |
- | return linkFunction; | + | |
- | } | + | |
- | } | + | |
- | }); | + | |
- | </ | + |