Mengakses atribut dari direktif AngularJS

95

Template AngularJS saya berisi beberapa sintaks HTML kustom seperti:

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

Saya membuat arahan untuk memprosesnya:

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

Semuanya berfungsi dengan baik, kecuali attrs.tooltipekspresi, yang selalu kembali undefined, meskipun tooltipatribut terlihat dari konsol JavaScript Google Chrome saat melakukanconsole.log(attrs) .

Ada saran?

UPDATE: Solusi ditawarkan oleh Artem. Itu terdiri dari melakukan ini:

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

AngularJS + stackoverflow = kebahagiaan

Ismael Ghalimi
sumber
Ini jawaban untuk pertanyaan lain menjelaskan bagaimana benar mengekspresikan terner di AngularJS.
Ismael Ghalimi
Jadi begini: "AngularJS + stackoverflow = bliss"
twip

Jawaban:

83

Lihat bagian Atribut dari dokumentasi tentang arahan.

mengamati atribut interpolasi : Gunakan $ observasi untuk mengamati perubahan nilai atribut yang mengandung interpolasi (mis. src = "{{bar}}"). Ini tidak hanya sangat efisien tetapi juga satu-satunya cara untuk dengan mudah mendapatkan nilai sebenarnya karena selama fase penautan interpolasi belum dievaluasi sehingga nilainya saat ini disetel ke tidak ditentukan.

Artem Andreev
sumber
2
URL sekarang diubah menjadi docs.angularjs.org/api/ng/service/$compile#Attributes
bhatiaravi
25

Meskipun menggunakan '@' lebih tepat daripada menggunakan '=' untuk skenario khusus Anda, terkadang saya menggunakan '=' sehingga saya tidak perlu ingat untuk menggunakan attrs. $ Observasi ():

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

Pengarahan:

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

Biola .

Dengan '=' kita mendapatkan penyatuan data dua arah, jadi kehati-hatian harus dilakukan untuk memastikan scope.title tidak dimodifikasi secara tidak sengaja dalam direktif. Keuntungannya adalah selama fase penautan, properti cakupan lokal (scope.title) ditentukan.

Mark Rajcok
sumber
Hai Mark, apa pendapat Anda tentang penggunaan solusi ini, apakah ada pedoman khusus untuk menggunakan observasi di link attrs terhadap penggunaan penyatuan data dua arah? Saya pikir terlihat lebih bersih untuk menggunakan penyatuan data dua arah tetapi saya bertanya-tanya apakah ada alasan untuk tidak menggunakannya?
Jeroen
@ Jeroen, saya memposting diskusi yang lebih panjang tentang penggunaan @vs di = sini .
Mark Rajcok