Доступ к атрибутам из директивы AngularJS

Мой шаблон AngularJS содержит некоторый собственный синтаксис HTML, например:

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

Я создал директиву для его обработки:

.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');
      }
    },
  }
})

Все работает отлично, за исключением выражения attrs.tooltip, которое всегда возвращает undefined, даже если атрибут tooltip отображается с консоли Google Chrome JavaScript при выполнении console.log(attrs).

Любое предложение?

ОБНОВЛЕНИЕ: решение было предложено Артемом. Он состоял в этом:

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

AngularJS + stackoverflow = блаженство

Ответ 1

См. раздел Attributes документации по директивам.

наблюдение интерполированных атрибутов: используйте $observ для наблюдения за изменениями значений атрибутов, которые содержат интерполяцию (например, src= "{{bar}}" ). Мало того, что это очень эффективно, но это также единственный способ легко получить фактическое значение, потому что во время фазы связывания интерполяция еще не была оценена, и поэтому значение в это время устанавливается на undefined.

Ответ 2

Хотя использование "@" более подходит, чем использование "=" для вашего конкретного сценария, иногда я использую "=", поэтому мне не нужно забывать использовать attrs. $observ():

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

Директива

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');
            }
        },
    }
});

Fiddle.

С '=' мы получаем двустороннюю привязку данных, поэтому необходимо соблюдать осторожность, чтобы scope.title не был случайно изменен в директиве. Преимущество заключается в том, что во время фазы связывания определено свойство локальной области (scope.title).