Accessing attributes from an AngularJS directive

123,493

Solution 1

See section Attributes from documentation on directives.

observing interpolated attributes: Use $observe to observe the value changes of attributes that contain interpolation (e.g. src="{{bar}}"). Not only is this very efficient but it's also the only way to easily get the actual value because during the linking phase the interpolation hasn't been evaluated yet and so the value is at this time set to undefined.

Solution 2

Although using '@' is more appropriate than using '=' for your particular scenario, sometimes I use '=' so that I don't have to remember to use attrs.$observe():

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

Directive:

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.

With '=' we get two-way databinding, so care must be taken to ensure scope.title is not accidentally modified in the directive. The advantage is that during the linking phase, the local scope property (scope.title) is defined.

Share:
123,493
Ismael Ghalimi
Author by

Ismael Ghalimi

Big Data Spreadsheet Builder

Updated on September 06, 2020

Comments

  • Ismael Ghalimi
    Ismael Ghalimi almost 4 years

    My AngularJS template contains some custom HTML syntax like:

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

    I created a directive to process it:

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

    Everything works fine, at the exception of the attrs.tooltip expression, which always returns undefined, even though the tooltip attribute is visible from Google Chrome's JavaScript console when doing a console.log(attrs).

    Any suggestion?

    UPDATE: A solution was offered by Artem. It consisted in doing this:

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

    AngularJS + stackoverflow = bliss