web-dev-qa-db-fra.com

Accès aux attributs depuis une directive AngularJS

Mon modèle AngularJS contient une syntaxe HTML personnalisée, telle que:

<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'expression attrs.tooltip, Qui renvoie toujours undefined, même si l'attribut tooltip est visible à partir de la console JavaScript de Google Chrome lors de l'exécution d'une fonction 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

94
Ismael Ghalimi

Voir la section Attributs de la documentation sur les directives.

observation des attributs interpolés : utilisez $ observ pour observer les modifications de valeur des attributs contenant 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 définie sur non définie.

83
Artem Andreev

Bien que l'utilisation de '@' soit plus appropriée que celle de '=' pour votre scénario particulier, j'utilise parfois '=' pour ne pas devoir me rappeler 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 modifié accidentellement dans la directive. L’avantage est que pendant la phase de liaison, la propriété de portée locale (scope.title) est définie.

25
Mark Rajcok