Accéder aux attributs depuis une directive AngularJS


95

Mon modèle AngularJS contient une syntaxe HTML personnalisée comme:

<su-label tooltip="{{field.su_documentation}}">{{field.su_name}}</su-label>

J'ai créé une directive pour le traiter:

.directive('suLabel', function() {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    scope: {
      title: '@tooltip'
    },
    template: '<label><a href="#" rel="tooltip" title="{{title}}" data-placement="right" ng-transclude></a></label>',
    link: function(scope, element, attrs) {
      if (attrs.tooltip) {
        element.addClass('tooltip-title');
      }
    },
  }
})

Tout fonctionne correctement, à l'exception de l' attrs.tooltipexpression, qui revient toujours undefined, même si l' tooltipattribut est visible depuis la console JavaScript de Google Chrome lors de l'exécution d'un fichier console.log(attrs).

Toute suggestion?

MISE À JOUR: Une solution a été proposée par Artem. Cela consistait à faire ceci:

link: function(scope, element, attrs) {
  attrs.$observe('tooltip', function(value) {
    if (value) {
      element.addClass('tooltip-title');
    }
  });
}

AngularJS + stackoverflow = bonheur


Cette réponse à une autre question explique comment exprimer correctement un ternaire dans AngularJS.
Ismael Ghalimi

Donc très ceci: "AngularJS + stackoverflow = bliss"
twip

Réponses:


83

Voir la section Attributs de la documentation sur les directives.

observation des attributs interpolés : utilisez $ observe pour observer les changements de valeur des attributs qui contiennent une interpolation (par exemple src = "{{bar}}"). Non seulement cela est très efficace, mais c'est aussi le seul moyen d'obtenir facilement la valeur réelle car pendant la phase de liaison, l'interpolation n'a pas encore été évaluée et la valeur est donc à ce moment définie sur indéfinie.



25

Bien que l'utilisation de '@' soit plus appropriée que d'utiliser '=' pour votre scénario particulier, j'utilise parfois '=' pour ne pas avoir à me souvenir d'utiliser attrs. $ Observe ():

<su-label tooltip="field.su_documentation">{{field.su_name}}</su-label>

Directif:

myApp.directive('suLabel', function() {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        scope: {
            title: '=tooltip'
        },
        template: '<label><a href="#" rel="tooltip" title="{{title}}" data-placement="right" ng-transclude></a></label>',
        link: function(scope, element, attrs) {
            if (scope.title) {
                element.addClass('tooltip-title');
            }
        },
    }
});

Violon .

Avec '=', nous obtenons une liaison de données bidirectionnelle, il faut donc veiller à ce que scope.title ne soit pas accidentellement modifié dans la directive. L'avantage est que pendant la phase de liaison, la propriété de portée locale (scope.title) est définie.


Hé Mark, quelle est votre opinion sur l'utilisation de ces solutions, existe-t-il une directive spécifique pour l'utilisation d'observer sur le lien attrs contre l'utilisation de la liaison de données bidirectionnelle? Je pense qu'il semble plus propre d'utiliser la liaison de données bidirectionnelle, mais je me demande s'il y a une raison de ne pas l'utiliser.
Jeroen

@Jeroen, j'ai posté une discussion plus longue sur l'utilisation de @vs = ici .
Mark Rajcok
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.