Dostęp do atrybutów z dyrektywy AngularJS

95

Mój szablon AngularJS zawiera niestandardową składnię HTML, taką jak:

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

Stworzyłem dyrektywę, aby to przetworzyć:

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

Wszystko działa dobrze, z wyjątkiem attrs.tooltipwyrażenia, które zawsze zwraca undefined, mimo że tooltipatrybut jest widoczny z konsoli JavaScript przeglądarki Google Chrome podczas wykonywania polecenia console.log(attrs).

Jakieś sugestie?

AKTUALIZACJA: Rozwiązanie zaproponował Artem. Polegał na tym:

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

AngularJS + stackoverflow = błogość

Ismael Ghalimi
źródło
Ta odpowiedź na inne pytanie wyjaśnia, jak poprawnie wyrazić trójskładnik w AngularJS.
Ismael Ghalimi
A więc tak: „AngularJS + stackoverflow = błogość”
twip

Odpowiedzi:

83

Zobacz sekcję Atrybuty z dokumentacji na temat dyrektyw.

obserwowanie atrybutów interpolowanych : użyj zmiennej $ obserwuj, aby obserwować zmiany wartości atrybutów zawierających interpolację (np. src = "{{bar}}"). Jest to nie tylko bardzo wydajne, ale także jedyny sposób na łatwe uzyskanie rzeczywistej wartości, ponieważ podczas fazy łączenia interpolacja nie została jeszcze oceniona, więc w tym momencie wartość jest ustawiona na niezdefiniowaną.

Artem Andreev
źródło
2
URL jest teraz zmieniony na docs.angularjs.org/api/ng/service/$compile#Attributes
bhatiaravi
25

Chociaż użycie znaku '@' jest bardziej odpowiednie niż użycie '=' dla twojego konkretnego scenariusza, czasami używam '=', aby nie musieć pamiętać o używaniu atrybutów. $ Obserwuj ():

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

Dyrektywa:

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

Skrzypce .

Z '=' otrzymujemy dwukierunkowe wiązanie danych, więc należy uważać, aby właściwość scope.title nie została przypadkowo zmodyfikowana w dyrektywie. Zaletą jest to, że podczas fazy łączenia definiowana jest właściwość zakresu lokalnego (scope.title).

Mark Rajcok
źródło
Hej Mark, jaka jest Twoja opinia na temat korzystania z tych rozwiązań, czy istnieją konkretne wytyczne dotyczące używania atrybutów follow na linku przeciwko używaniu dwukierunkowego wiązania danych? Wydaje mi się, że użycie dwukierunkowego wiązania danych wygląda czyściej, ale zastanawiam się, czy istnieje powód, aby go nie używać?
Jeroen,
@Jeroen, opublikowałem dłuższą dyskusję na temat używania @vs = tutaj .
Mark Rajcok