2013-06-27 3 views
21

Как использовать значение атрибута в директиве? Мой элемент выглядит следующим образом:Использовать атрибуты угловой директивы в шаблоне

<div class="tooltip-icon" 
    data-my-tooltip="click" 
    data-tooltip-title="foo" 
    data-tooltip-content="test content"></div> 

Я хотел бы использовать это в шаблоне моей директивы, которая выглядит следующим образом:

mainApp.directive('myTooltip', 
    function() { 

     // allowed event listeners 
     var allowedListeners = ["click"]; 

     return { 
      restrict: 'A', 
      template: '<div class="tooltip-title">...</div>' + 
         '<div class="tooltip-content">' + 
         '...</div>', 
      link: function(scope, elm, attrs) { 
       if(allowedListeners.indexOf(attrs.myTooltip) != -1){ 
        elm.bind(attrs.myTooltip, function(){ 
         ... 
        }); 
       } 

      } 
     }; 
    } 
); 

Где тройные точки находятся там должен быть код, но я не может понять, как получить содержимое объекта attrs (attrs.tooltipTitle и т. д.) в этот шаблон.

ответ

32

Вы можете вытащить атрибуты, и поместить их в сферу действия директивы, как это:

angular.module('myApp', []). 
directive('myTooltip', function ($log) { 
    // allowed event listeners 
    var allowedListeners = ["click"]; 
    return { 
     restrict: 'A', 
     template: '<div class="tooltip-title">{{tooltipTitle}}</div>' + 
        '<div class="tooltip-content">' + 
        '{{tooltipContent}}</div>', 
     scope: { 
      tooltipTitle: '@tooltipTitle', 
      tooltipContent: '@tooltipContent' 
     }, 
     link: function (scope, elm, attrs) { 
      if (allowedListeners.indexOf(attrs.myTooltip) != -1) { 
       elm.bind(attrs.myTooltip, function() { 
        $log.info('clicked'); 
       }); 
      } 

     } 
    }; 
}); 

Вот скрипку: http://jsfiddle.net/moderndegree/f3JL3/

+0

Что касается области, то \ @tooltipTitle и \ @tooltipcontent вытягивают содержимое только в область этого экземпляра, т. Е. Могут ли я иметь 2 всплывающие подсказки на одной странице, и они не будут перезаписывать название и содержимое каждой из них? – Maarten

+1

Вы должны иметь на странице столько, сколько хотите. Он вытягивается из атрибутов DOM. Вы можете узнать больше о том, как я это сделал здесь: http://docs.angularjs.org/guide/directive#directivedefinitionobject –

3

Этот вопрос уже уже был дан ответ, но я м, чтобы разделить мой Угловой код, так как это одна из областей, где часто бывает полезно увидеть несколько рабочих примеров.

У меня есть несколько веб-страниц, каждый со своим собственным угловым контроллером, и я хотел способ иметь один «Пожалуйста, подождите» всплывающие окна на каждой странице, которая появляется, когда какой-либо из страниц называется HTTP GET или POST веб-сервис.

enter image description here

Чтобы сделать это, каждый из моих веб-страниц содержит следующую строку:

<please-wait message="{{LoadingMessage}}" ></please-wait> 

..., который связан с $scope в контроллере этой страницы ...

$scope.LoadingMessage = "Loading the surveys..."; 

Вот код для моей <please-wait> директивы:

myApp.directive('pleaseWait', 
    function ($parse) { 
     return { 
      restrict: 'E', 
      replace: true, 
      scope: { 
       message: '@message' 
      }, 
      link: function (scope, element, attrs) { 
       scope.$on('app-start-loading', function() { 
        element.fadeIn(); 
       }); 
       scope.$on('app-finish-loading', function(){ 
        element.animate({ 
         top: "+=15px", 
         opacity: "0" 
        }, 500); 
       }); 
      }, 
      template: '<div class="cssPleaseWait"><span>{{ message }}</span></div>' 
     } 
    }); 

Обратите внимание на то, как он набирает атрибут message ({{LoadingMessage}} в этом примере) и может отображать его значение в шаблоне директивы.

(Это на самом деле только часть моего ответа, который непосредственно отвечает на этот вопрос, но читать, в течение еще нескольких tips'n'tricks ...)

Теперь, прохладная часть является то, что каждый из моих контроллеры звонят в Угловую службу данных всякий раз, когда она хочет загружать или сохранять любые данные из/в веб-службу.

$scope.LoadAllSurveys = function() { 
     DataService.dsLoadAllSurveys($scope).then(function (response) { 
      // Success 
      $scope.listOfSurveys = response.GetAllSurveysResult; 
     }); 
    } 

dsLoadAllSurveys функция выглядит следующим образом ...

myApp.webServicesURL = "http://localhost:15021/Service1.svc"; 

myApp.factory('DataService', ['$http', 'httpPostFactory', 'httpGetFactory', 
    function ($http, httpPostFactory, httpGetFactory) { 

     var dsLoadAllSurveys = function (scope) 
     { 
      // Load all survey records, from our web server 
      var URL = myApp.webServicesURL + "/getAllSurveys"; 
      return httpGetFactory(scope, URL); 
     } 

     return { 
      dsLoadAllSurveys: dsLoadAllSurveys 
     } 
    }]); 

И, самое главное, все «ПОЛУЧИТЬ» вызовы веб-службы идут через следующую функцию, которая отображает элемент управления Пожалуйста, подождите нас .. затем он уходит, когда услуга завершена.

myApp.factory('httpGetFactory', function ($http, $q) { 
    return function (scope, URL) { 
     // This Factory method calls a GET web service, and displays a modal error message if something goes wrong. 
     scope.$broadcast('app-start-loading');   // Show the "Please wait" popup 

     return $http({ 
      url: URL, 
      method: "GET", 
      headers: { 'Content-Type': undefined } 
     }).then(function (response) { 
      scope.$broadcast('app-finish-loading');  // Hide the "Please wait" popup 
      if (typeof response.data === 'object') { 
       return response.data; 
      } else { 
       // invalid response 
       return $q.reject(response.data); 
      } 
     }, function (errorResponse) { 
      scope.$broadcast('app-finish-loading');  // Hide the "Please wait" popup 

      // The WCF Web Service returned an error. 
      // Let's display the HTTP Status Code, and any statusText which it returned. 
      var HTTPErrorNumber = (errorResponse.status == 500) ? "" : "HTTP status code: " + errorResponse.status + "\r\n"; 
      var HTTPErrorStatusText = errorResponse.statusText; 

      var message = HTTPErrorNumber + HTTPErrorStatusText; 

      BootstrapDialog.show({ 
       title: 'Error', 
       message: message, 
       buttons: [{ 
        label: 'OK', 
        action: function (dialog) { 
         dialog.close(); 
        }, 
        draggable: true 
       }] 
      }); 

      return $q.reject(errorResponse.data); 
     }); 
    }; 
}); 

То, что я люблю этот код является то, что это одна функция выглядит после показа/скрытия «Пожалуйста, подождите» всплывающее окно, и в случае возникновения ошибки, она также выглядит после вывода на экране сообщения об ошибке (используя отличную BootstrapDialog библиотеки), прежде чем вернуть результат ошибки обратно вызывающему абоненту.

Без функции эта функция фабрики, каждый раз, когда один из моих угловых контроллеров будет вызывать веб-службу, ей нужно будет показать, затем скрыть элемент «Подождите» и проверить наличие ошибок.

Теперь я могу позвонить в свой веб-сервис и оставить его, чтобы сообщить пользователю, если что-то пойдет не так, иначе я могу предположить, что все сработало и обрабатывает результаты.

Это позволяет мне иметь гораздо более простой код. Помните, как я назвал это веб-сервис:

DataService.dsLoadAllSurveys($scope).then(function (response) { 
     // Success 
     $scope.listOfSurveys = response.GetAllSurveysResult; 
    }); 

Этот код выглядит как будто это не делает каких-либо обработки ошибок, в то время как на самом деле, все это после того, как посмотрел за кулисами в одном месте.

Я все еще получаю завесу заводов и служб передачи данных с помощью Angular, но я думаю, что это примерный пример того, как они могут помочь.

Надеюсь, что это имело смысл и помогает.