2013-06-27 42 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的工廠和數據服務,但我認爲這是他們如何提供幫助的一個令人震驚的例子。

希望這是有道理的,並幫助。