Toegang tot attributen uit een AngularJS-richtlijn

Mijn AngularJS-sjabloon bevat een aantal aangepaste HTML-syntaxis zoals:

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

Ik heb een richtlijn gemaakt om deze te verwerken:

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

Alles werkt prima, met uitzondering van de uitdrukking attrs.tooltip, die altijd undefinedretourneert, ook al is het kenmerk tooltipzichtbaar van de JavaScript-console van Google Chrome bij het uitvoeren van een console.log(attrs).

Enige suggestie?

UPDATE: Artem bood een oplossing. Het bestond erin om dit te doen:

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

AngularJS + stackoverflow = gelukzaligheid


Antwoord 1, autoriteit 100%

Zie sectie Kenmerkenvan documentatie over richtlijnen.

geïnterpoleerde attributen observeren: gebruik $observe om de waardeveranderingen te observeren van attributen die interpolatie bevatten (bijv. src=”{{bar}}”). Dit is niet alleen erg efficiënt, maar het is ook de enige manier om gemakkelijk de werkelijke waarde te krijgen, omdat tijdens de koppelingsfase de interpolatie nog niet is geëvalueerd en daarom is de waarde op dit moment ingesteld op ongedefinieerd.


Antwoord 2, autoriteit 30%

Hoewel het gebruik van ‘@’ geschikter is dan het gebruik van ‘=’ voor uw specifieke scenario, gebruik ik soms ‘=’ zodat ik niet hoef te onthouden dat ik attrs.$observe() moet gebruiken:

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

Richtlijn:

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.

Met ‘=’ krijgen we gegevensbinding in twee richtingen, dus er moet voor worden gezorgd dat scope.title niet per ongeluk wordt gewijzigd in de richtlijn. Het voordeel is dat tijdens de koppelingsfase de eigenschap local scope (scope.title) wordt gedefinieerd.

Other episodes