24

如何在指令中使用属性的值?我的元素如下所示:

<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等)的内容放入该模板中。

4

2 回答 2

34

您可以将属性拉出并将它们放入指令的范围内,如下所示:

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/

于 2013-06-27T14:38:12.267 回答
3

这个问题已经得到解答,但我也将分享我的 Angular 代码,因为在这个领域中,查看一些工作示例通常很有用。

我有几个网页,每个网页都有自己的 Angular 控制器,我想要一种在每个页面上都有一个“请稍候”弹出窗口的方法,当任何页面调用 HTTP GET 或 POST Web 服务时就会出现。

在此处输入图像描述

为此,我的每个网页都包含以下行:

<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 数据服务,只要它想从/向 Web 服务加载或保存任何数据。

   $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”Web 服务调用都通过以下函数进行,该函数为我们显示 Please Wait 控件...然后在服务完成后使其消失。

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库)之后查看,然后返回错误结果回到调用者。

如果没有这个工厂函数,每次我的 Angular 控制器调用 Web 服务时,它都需要显示、然后隐藏“请稍候”控件,并检查错误。

现在,我可以调用我的 Web 服务,如果出现问题,会通知用户,否则我可以假设它一切正常,并处理结果。

这让我有更简单的代码。记住我是如何调用该 Web 服务的:

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

该代码看起来好像没有进行任何错误处理,而实际上,它都在一个地方在幕后进行了处理。

我仍然对 Angular 的工厂和数据服务有所了解,但我认为这是他们如何提供帮助的一个令人震惊的例子。

希望这是有道理的,并有所帮助。

于 2016-09-01T19:12:12.013 回答