2013-06-27 54 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

这个问题已经回答了,但我我也会分享我的Angular代码,因为这是一个通常可以看到几个实例的领域。

我有几个网页,每个都有自己的角度控制,我想办法把一个“请等待”弹出每一页,当任一页面的叫其将出现在一个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 ...)

现在,最酷的部分是,我的每一个控制器只要想要加载或保存任何来自Web服务的数据,就会调用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” Web服务调用通过下面的函数,这显示我们请等待控制去..然后在服务完成时使其消失。

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服务时,它需要显示,然后隐藏“Please wait”控件,并检查错误。

现在,我可以打电话给我的网络服务,并将其通知用户是否出现问题,否则我可以认为它是所有工作,并处理结果。

这使我有更简单的代码。还记得我怎么叫,网页服务:

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

该代码看起来好像它没有做任何错误处理,而实际上,这一切都在一个地方照顾幕后。

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

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