Подтвердить что ты не робот

Использовать атрибуты директивы Angular в шаблоне

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

<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 и т.д.) в этот шаблон.

4b9b3361

Ответ 1

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

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/

Ответ 2

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

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

введите описание изображения здесь

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

<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}} в этом примере) и может отображать его значение в шаблоне директивы.

(Это на самом деле единственная часть моего ответа, которая непосредственно отвечает на этот вопрос, но читайте дальше, еще несколько советов ")

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

   $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
        }
    }]);

И, что важно, все вызовы веб-службы "GET" проходят через следующую функцию, которая отображает элемент "Подождите" для нас... затем он уходит, когда служба завершена.

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 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, перед возвратом результата ошибки обратно вызывающему.

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

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

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

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

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

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

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