Zugriff auf Attribute über eine AngularJS-Direktive

95

Meine AngularJS-Vorlage enthält eine benutzerdefinierte HTML-Syntax wie:

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

Ich habe eine Direktive erstellt, um sie zu verarbeiten:

.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 funktioniert einwandfrei, mit Ausnahme des attrs.tooltipAusdrucks, der immer zurückgegeben wird undefined, obwohl das tooltipAttribut in der JavaScript-Konsole von Google Chrome sichtbar ist, wenn Sie a ausführen console.log(attrs).

Irgendein Vorschlag?

UPDATE: Eine Lösung wurde von Artem angeboten. Es bestand darin:

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

AngularJS + Stackoverflow = Glückseligkeit

Ismael Ghalimi
quelle
Diese Antwort auf eine andere Frage erklärt, wie ein Ternär in AngularJS richtig ausgedrückt wird.
Ismael Ghalimi
Also genau das: "AngularJS + stackoverflow = bliss"
twip

Antworten:

83

Siehe Abschnitt Attribute aus der Dokumentation zu Direktiven.

Beobachten interpolierter Attribute : Verwenden Sie $ beobachten, um die Wertänderungen von Attributen zu beobachten, die Interpolation enthalten (z. B. src = "{{bar}}"). Dies ist nicht nur sehr effizient, sondern auch die einzige Möglichkeit, den tatsächlichen Wert einfach zu ermitteln, da während der Verknüpfungsphase die Interpolation noch nicht ausgewertet wurde und der Wert zu diesem Zeitpunkt auf undefiniert gesetzt ist.

Artem Andreev
quelle
2
Die URL wurde jetzt in docs.angularjs.org/api/ng/service/$compile#Attributes
bhatiaravi
25

Obwohl die Verwendung von '@' für Ihr spezielles Szenario besser geeignet ist als die Verwendung von '=', verwende ich manchmal '=', damit ich nicht daran denken muss, attrs zu verwenden. $ Observ ():

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

Richtlinie:

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

Geige .

Mit '=' erhalten wir eine bidirektionale Datenbindung, daher muss darauf geachtet werden, dass scope.title in der Direktive nicht versehentlich geändert wird. Der Vorteil ist, dass während der Verknüpfungsphase die lokale Bereichseigenschaft (scope.title) definiert wird.

Mark Rajcok
quelle
Hey Mark, wie ist Ihre Meinung zur Verwendung dieser Lösungen? Gibt es eine spezielle Richtlinie für die Verwendung von Observ auf den Link-Attributen gegen die Verwendung der Zwei-Wege-Datenbindung? Ich denke, es sieht sauberer aus, die bidirektionale Datenbindung zu verwenden, aber ich frage mich, ob es einen Grund gibt, sie nicht zu verwenden.
Jeroen
@Jeroen, ich gepostet eine längere Diskussion mit @vs = hier .
Mark Rajcok