指令(directive)是AngularJS核心模块之一,可以实现很多强大的功能,那么指令和多控制器之间的交互是如何实现的呢?请花费两分钟阅读下文!

站内文章“指令的三个阶段”中提到,大部分时候我们只需要编写link函数,其中包括DOM操作、时间绑定、函数调用等。

一、指令复用时调用控制器的方法

1. HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div ng-controller="MyCtrl">
<loader howToLoad="loadData()">滑动加载</loader>
</div>
<div ng-controller="MyCtrl2">
<loader howToLoad="loadData2()">滑动加载</loader>
</div>
</body>
<script src="https://cdn.bootcss.com/angular.js/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="js/controller.js" ></script>
</html>

这里定义angualrjs应用MyModule,在不同的控制器使用自定义指令loader,指令里面定义属性howToLoad,属性值为控制器里面函数的调用。

2. javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var myModule = angular.module("MyModule", []);

myModule.controller('MyCtrl',['$scope', function($scope){
$scope.loadData = function(){
console.log("加载数据中...");
};
}]);

myModule.controller('MyCtrl2',['$scope', function($scope){
$scope.loadData2 = function(){
console.log("加载数据中222...");
};
}]);

myModule.directive("loader",function(){
return {
restrict: "AE",
link: function(scope, element, attrs){
element.bind("mouseenter", function(event){
scope.$apply(attrs.howtoload); //转换成小写
})
}
}
})

分别在不同的控制器定义不同函数,在指令的link函数中绑定鼠标事件,传入自定义指令的属性值,调用对应的函数。

3. 归纳:

自定义指令和多控制器交互,主要是通过复用指令时传入不同的属性值(不同的函数),在指令的link函数中调用实现的,注意link函数中取自定义属性会被转成小写。

二、指令与控制器之间的数据绑定

1. scope的三种绑定方式:

类型 描述
@ 把当前属性作为字符串传递。你还可以绑定来自外层scope的值,在属性值中插入{ { } }即可
= 与父scope中的属性进行双向绑定
& 传递一个来自父scope的函数,稍后调用

2. @绑定方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8" />
<title></title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/angular.js/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="js/myController.js" ></script>
</head>
<body>
<div class="" ng-controller="MyCtrl">
<drink flavor="{{ctrlFlavor}}"></drink>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var myModule = angular.module("MyModule",[]);

myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.ctrlFlavor="百威";
}])

myModule.directive("drink", function(){
return {
restrict: 'AE',
scope: {
flavor: '@'
},
template: "<div>{{flavor}}</div>"
// ,
// link: function(scope, element, attrs){
// scope.flavor = attrs.flavor;
// }
}
});

自定义指令的flavor属性值用{ { } }表达式,给指令的scope绑定对应的@符号,可以代替link函数中的重新赋值。

3. =绑定方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8" />
<title></title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/angular.js/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="js/myController.js" ></script>
</head>
<body>
<div class="" ng-controller="MyCtrl">
控制器:
<br />
<input type="text" ng-model="ctrlFlavor" />
<br />
指令:
<br />
<drink flavor="ctrlFlavor"></drink>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var myModule = angular.module("MyModule",[]);

myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.ctrlFlavor="百威";
}])

myModule.directive("drink", function(){
return {
restrict: 'AE',
scope: {
flavor: '='
},
template: '<input type="text" ng-model="flavor" />'
}
});

控制器的input绑定控制器的ctrlFlavor数据,指令template的input绑定指令域的flavor属性,通过=符号实现数据的双向绑定。

4. &绑定方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8" />
<title></title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/angular.js/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="js/myController.js" ></script>
</head>
<body>
<div class="" ng-controller="MyCtrl">
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var myModule = angular.module("MyModule",[]);

myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.sayHello = function(name){
alert("Hello "+name);
};
}])

myModule.directive("greeting", function(){
return {
restrict: 'AE',
scope: {
greet: '&'
},
template: '<input type="text" ng-model="userName" />' +
'<button class="btn btn-default" ng-click="greet({name:userName})">问候</button><br />'
}
});

自定义指令的greet属性绑定了控制器的sayHello方法,传入name值,自定义指令中input绑定用户输入的数据userName,通过ng-click事件调用greet属性传过来的值。