web-dev-qa-db-fra.com

Comment appliquer une directive AngularJS basée sur une classe définie par ng-class?

J'essaie d'appliquer conditionnellement une directive à un élément en fonction de sa classe.

Voici un cas simple de mon numéro, voir les résultats dans ce violon . Pour cet exemple, j'utilise la carte des noms de classe en booléens sous la forme ng-class avec true; dans mon cas, j'aimerais utiliser le résultat booléen d'une fonction.

Balisage:

<div ng-app="example">
  <div class="testcase">
    This will have the directive applied as I expect
  </div>
  <div ng-class="{'testcase':true}">
    This will not have the directive applied but I expect it to
  </div>
</div>

JS:

angular.module('example', [])
  .directive('testcase', function() {
      return {
          restrict: 'C',
          link: function(scope, element, attrs) {
              element.css('color', 'red');
          }
      }
    }
  );

Pourquoi la directive n'est-elle pas appliquée à la div dont la classe passe par ng-class? Est-ce que je comprends mal l’ordre dans lequel AngularJS traite les directives?

Comment dois-je appliquer conditionnellement une directive à un élément basé sur l'évaluation d'une expression?

42
carols10cents

ng-class définit simplement les classes sur le DOM, après le processus de compilation.

Une meilleure façon d'appliquer la directive serait peut-être d'utiliser un attribut HTML:

<div test-case>

Bien sûr, ce n'est pas conditionnel, mais je laisserais le conditionnement à la directive:

<div ng-app="example" ng-controller="exampleCtrl">
    <div test-case condition="dynamicCondition">Hello</div>
    <input type="checkbox" ng-model="dynamicCondition"/> Condition 
</div>

et

angular.module('example', [])
    .controller('exampleCtrl', function ($scope) {
        $scope.dynamicCondition = false;
    })
    .directive('testCase', function () {
    return {
        restrict: 'A',
        scope: {
            'condition': '='
        },
        link: function (scope, element, attrs) {
            scope.$watch('condition', function(condition){
                if(condition){
                    element.css('color', 'red');
                }
                else{
                    element.css('color', 'black');
                };
            });
        }
    }
});

Notez que le nom de la directive est testCaseau lieu de testcase, le bit scope: {'condition': '='}, garantit que l'attribut condition est synchronisé et disponible en tant que scope.condition et que watch évalue le deuxième argument chaque fois que l'expression de la première valeur modifiée. JsFiddle par ici .

Peut-être devriez-vous aussi vous pencher sur ng-switch :

<div ng-switch="conditionFunction()">
  <div ng-when="true" test-case>Contents when conditionFunction() returns true</div>
  <div ng-when="false">Contents when conditionFunction() returns false</div>
</div>
24
Jair Trejo
angular.module('example', [])
  .directive('testCase', function() {
      return {
          restrict: 'C',
          link: function(scope, element, attrs) {
            element.css('color', 'red');
          }
      }
    })
1
Punnith DJ

Selon moi, n'utilisez pas de directive conditionnelle basée sur une classe définie par ng-class comme cette question.

N'utilisez pas ceci

<div ng-app="example">
  <div class="testcase">
    This will have the directive applied as I expect
  </div>
  <div ng-class="{'testcase':true}">
    This will not have the directive applied but I expect it to
  </div>
</div>

car il est très compliqué à gérer dans une situation complexe, utilisez donc toujours les conditions dans votre directive personnalisée.

Utilisez ceci

link: function (scope, element, attrs) {
    scope.$watch('condition', function(condition){
        if(condition){
            // something going here
        }
        else{
            // something going here
        };
    });
}
0
Gaurav