【问题标题】:Use Angular Directive attributes in its template在其模板中使用 Angular Directive 属性
【发布时间】:2023-04-09 22:32:01
【问题描述】:

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

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

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案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/

    【讨论】:

    • 至于范围,\@tooltipTitle 和 \@tooltipcontent 是否仅将内容拉入此实例的范围,即我可以在同一页面上有 2 个工具提示并且它们不会相互覆盖标题和内容?
    • 您应该能够在页面上拥有任意数量的内容。它是从 DOM 属性中提取的。你可以在这里找到更多关于我是如何做到的:docs.angularjs.org/guide/directive#directivedefinitionobject
    【解决方案2】:

    这个问题已经已经回答了,但我也将分享我的 Angular 代码,因为这是一个经常可以查看一些工作示例的领域。

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

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

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

    ...绑定到该页面控制器中的$scope...

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

    这是我的&lt;please-wait&gt; 指令的代码:

    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 服务,并留下 it 通知用户如果出现问题,否则我可以假设一切正常,并处理结果。

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      相关资源
      最近更新 更多