前面練習了如何自定義指令,這里練習一下指令在不同的控制器中如何復用。
—— 來自《慕課網 指令3》
首先看一下一個小例子,通過自定義指令,捕獲鼠標事件,並觸發控制器中的方法。
單個控制器的標簽指令
依然是先創建一個模塊
var myAppModule = angular.module("myApp",[]);
在模塊的基礎上,創建控制器和指令
myAppModule.controller("myAppCtrl",["$scope",function($scope){
$scope.count = 0;
$scope.loadData = function(){
$scope.count = $scope.count+1;
console.log("myAppCtrl load data!"+$scope.count);
}
}]);
myAppModule.directive("loader",function(){
return{
restrict:"AE",
transclude:true,
template:"<div><div ng-transclude></div></div>",
link:function(scope,element,attr){
element.bind("mouseenter",function(){
// scope.loadData();
scope.$apply("loadData()");
});
}
}
});
首先看一下創建的控制器,在其中創建了一個loadData方法,用於相應觸發事件,為了便於觀察結果,添加了一個計數器。
下面的指令采用了屬性和標簽元素的使用方式:“AE”,為了得到效果,創建了一個內嵌的模板(避免沒有內容時,點擊不到)。
並在link屬性的方法內,添加相應事件,方法中有三個參數:
1 scope,作用域,用於調用相應的作用域的方法。
2 element,指代創建的標簽
3 attr,用於擴展屬性,稍后展示使用方法
有了以上的准備工作,就可以在body里面使用標簽了:
<div ng-controller="myAppCtrl">
<loader howToLoad="loadData()">第一個loader!</loader>
</div>
如何復用指令
以上僅僅是單個控制器的指令使用,一個指令在一個頁面中可以被多次使用,也就意味着,會有多個控制器使用該指令。
那么指令如何知道調用控制器的那個方法呢?這就用到了attr屬性。
在創建指令時,調用attr獲取屬性的值
myAppModule.directive("loader",function(){
return{
restrict:"AE",
transclude:true,
template:"<div><div ng-transclude></div></div>",
link:function(scope,element,attr){
element.bind("mouseenter",function(){
// scope.loadData();
// scope.$apply("loadData()");
scope.$apply(attr.howtoload);
});
}
}
});
就可以在body中按照如下的方式使用了:
<div ng-controller="myAppCtrl">
<loader howToLoad="loadData()">第一個loader!</loader>
</div>
<div ng-controller="myAppCtrl2">
<loader howToLoad="loadData2()">第二個loader!</loader>
</div>
需要注意的是:
1 標簽中屬性使用駝峰法命名,在指令中要轉換成全部小寫。
2 指令中調用的僅僅是屬性的名字,沒有方法括號。
3 應用時,屬性對應的值是該控制器內聲明的執行方法。
下面看一下樣例代碼:
<!doctype html>
<html ng-app="myApp">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
</head>
<body>
<div ng-controller="myAppCtrl">
<loader howToLoad="loadData()">第一個loader!</loader>
</div>
<div ng-controller="myAppCtrl2">
<loader howToLoad="loadData2()">第二個loader!</loader>
</div>
<script type="text/javascript">
var myAppModule = angular.module("myApp",[]);
myAppModule.controller("myAppCtrl",["$scope",function($scope){
$scope.count = 0;
$scope.loadData = function(){
$scope.count = $scope.count+1;
console.log("myAppCtrl load data!"+$scope.count);
}
}]);
myAppModule.controller("myAppCtrl2",["$scope",function($scope){
$scope.count = 0;
$scope.loadData2 = function(){
$scope.count = $scope.count+1;
console.log("myAppCtrl2 load data!"+$scope.count);
}
}]);
myAppModule.directive("loader",function(){
return{
restrict:"AE",
transclude:true,
template:"<div><div ng-transclude></div></div>",
link:function(scope,element,attr){
element.bind("mouseenter",function(){
// scope.loadData();
// scope.$apply("loadData()");
scope.$apply(attr.howtoload);
});
}
}
});
</script>
</body>
</html>
實現的結果:

