指令是什么? 指令是我们用来扩展浏览器能力的技术之一。在DOM编译期间,和HTML关联着的指令会被检测到,并且被执行。这使得指令可以为DOM指定行为,或者改变它。
1.指令的匹配模式
index.html :
1 <!doctype html>
2 <html ng-app="MyModule">
3 <head>
4 <meta charset="utf-8">
5 </head>
6 <body>
7 <hello></hello>
8 <div hello></div>
9 <div class="hello"></div>
10 <!-- directive:hello -->
11 <div></div>
12 </body>
13 <script src="framework/angular-1.3.0.14/angular.js"></script>
14 <script src="HelloAngular_Directive.js"></script>
15 </html>
helloAngular_Directive.js :
1 var myModule = angular.module("MyModule"
, []);
2 myModule.directive("hello",
function() {
3 return {
4 restrict: 'AEMC'
,
5 template: '<div>Hi everyone!</div>'
,
6 replace:
true
7 }
8 });
html中包含五个元素,其中一个是注释的元素,JS中定义了一个模块和模块的指令。
OK,不要急,先来看一下
directive 是什么意思,directive的意思是指令,顾名思义,定义一个指令,名字叫 “hello”.
首先,看一下
restrict , restrict的意思是限制,约束。也就是要讲的指令的匹配模式,共有四种:
(1)E: 元素(即html中的<hello></hello>);
(2)A(默认) :属性 (<div hello></div>);
(3)C: 样式类(<div class="hello"></div>)
(4)M: 注释(<!-- directive:hello -->)
常用 A E , 推荐使用这两个。下图就是匹配到的指令元素,并替换了元素的内容,至于怎么替换的内容,继续往下看。
接下来,看一下
template ,template的意思是模板,也就是要替换的内容。但是在js中组织和拼接div这些元素的代码,很费劲的。怎么办呢。有办法,那就是
templateUrl, 把要替换的元素内容写到一个页面里面。嗯如下所示:
1 var myModule = angular.module("MyModule"
, []);
2 myModule.directive("hello",
function() {
3 return {
4 restrict: 'AECM'
,
5 templateUrl: 'hello.html'
,
6 replace:
true
7 }
8 });
如果我们想要在别的指令中也是用这个hello.html怎么办,那么就有出现了一个缓存的解决办法。看下面的 run 方法在加载完所有模块后,只执行一次,然后把模板缓存起来,当有指令需要调用时,就调用
$templateCache.get().
1 var myModule = angular.module("MyModule"
, []);
2 //注射器加载完所有模块时,此方法执行一次
3 myModule.run(
function($templateCache){
4 $templateCache.put("hello.html","<div>Hello everyone!!!!!!</div>"
);
5 });
6 myModule.directive("hello",
function($templateCache) {
7 return {
8 restrict: 'AECM'
,
9 template: $templateCache.get("hello.html"
),
10 replace:
true
11 }
12 });
接下来,再看一下
replace(”替换“),replace:true 会替换元素的内容。但是不想替换内容只是想添加一个内容呢,,没事,,还有
transclude
1 var myModule = angular.module("MyModule"
, []);
2 myModule.directive("hello",
function() {
3 return {
4 restrict:"AE"
,
5 transclude:
true,
6 template:"<div>Hello everyone!<div ng-transclude></div></div>"
7 }
8 });
最后介绍一下AngularJS的运行机制:
2.指令和控制器的交互。
index.html :
1 <!doctype html>
2 <html ng-app="MyModule">
3 <head>
4 <meta charset="utf-8">
5 </head>
6 <body>
7 <div ng-controller="MyCtrl">
8 <loader howToLoad="loadData()">滑动加载
</loader>
9 </div>
10 <div ng-controller="MyCtrl2">
11 <loader howToLoad="loadData2()">滑动加载
</loader>
12 </div>
13 </body>
14 <script src="framework/angular-1.3.0.14/angular.js"></script>
15 <script src="Directive&Controller.js"></script>
16 </html>
Directive&Controller.js :
1 var myModule = angular.module("MyModule"
, []);
2 myModule.controller('MyCtrl', ['$scope',
function($scope){
3 $scope.loadData=
function(){
4 console.log("加载数据中..."
);
5 }
6 }]);
7 myModule.controller('MyCtrl2', ['$scope',
function($scope){
8 $scope.loadData2=
function(){
9 console.log("加载数据中...22222"
);
10 }
11 }]);
12 myModule.directive("loader",
function() {
13 return {
14 restrict:"AE"
,
15 link:
function(scope,element,attrs){
16 element.bind('mouseenter',
function(event) {
17 //(1)scope.loadData();
18 //(2)scope.$apply("loadData()");
19 // 注意这里的坑,howToLoad会被转换成小写的howtoload
20 scope.$apply(attrs.howtoload);
21 });
22 }
23 }
24 });
现在我们想要实现的效果是当鼠标滑过div元素时,调用一个加载数据的方法。
hmtl中我们定义了两个控制器,然后两个控制器中都使用了
loader指令,并且,每个指令中都有一个参数
howToLoad .
关于指令中的
link ,上面介绍运行机制是已经看到了,是用来操作dom和绑定监听事件的。link中会有三个参数:
scope(指令所属的控制器中的 $scope 对象)、
element(指令所属dom元素)、
attrs(dom元素所传的参数,如howToLoad 参数给的值 loadData()).
然后对于如何调用所需函数,有两种方法:
(1)
scope.loadData() ,这种方法是有局限的,如,MyCtrl1 控制器中的指令所调用的方法是MyCtrl1控制器中所定义的loadData() 方法,但是MyCtrl2就会报错了,因为没有loadData(). 所有就有了另个一个方法。
(2)
scope.$apply() , $apply()方法会从所有控制器中找到多对应的方法。这就实现了指令的复用。
3.指令间的交互。
index.html :
1 <!doctype html>
2 <html ng-app="MyModule">
3 <head>
4 <meta charset="utf-8">
5 <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
6 <script src="framework/angular-1.3.0.14/angular.js"></script>
7 <script src="Directive&Directive.js"></script>
8 </head>
9 <body>
10 <div class="row">
11 <div class="col-md-3">
12 <superman strength>动感超人---力量
</superman>
13 </div>
14 </div>
15 <div class="row">
16 <div class="col-md-3">
17 <superman strength speed>动感超人2---力量+敏捷
</superman>
18 </div>
19 </div>
20 <div class="row">
21 <div class="col-md-3">
22 <superman strength speed light>动感超人3---力量+敏捷+发光
</superman>
23 </div>
24 </div>
25 </body>
26 </html>
Directive&Directive.js :
1 var myModule = angular.module("MyModule"
, []);
2 myModule.directive("superman",
function() {
3 return {
4 scope: {},
//独立作用域
5 restrict: 'AE'
,
6 controller:
function($scope) {
7 $scope.abilities =
[];
8 this.addStrength =
function() {
9 $scope.abilities.push("strength"
);
10 };
11 this.addSpeed =
function() {
12 $scope.abilities.push("speed"
);
13 };
14 this.addLight =
function() {
15 $scope.abilities.push("light"
);
16 };
17 },
18 link:
function(scope, element, attrs) {
19 element.addClass('btn btn-primary'
);
20 element.bind("mouseenter",
function() {
21 console.log(scope.abilities);
22 });
23 }
24 }
25 });
26 myModule.directive("strength",
function() {
27 return {
28 require: '^superman'
,
29 link:
function(scope, element, attrs, supermanCtrl) {
30 supermanCtrl.addStrength();
31 }
32 }
33 });
34 myModule.directive("speed",
function() {
35 return {
36 require: '^superman'
,
37 link:
function(scope, element, attrs, supermanCtrl) {
38 supermanCtrl.addSpeed();
39 }
40 }
41 });
42 myModule.directive("light",
function() {
43 return {
44 require: '^superman'
,
45 link:
function(scope, element, attrs, supermanCtrl) {
46 supermanCtrl.addLight();
47 }
48 }
49 });
定义了一个superman的指令和另外三个指令,分别是strength、speed、light、
后面三个指令都有一个
require 参数,是指都依赖superman指令,link中的最后一个参数就是superman指令的引用。
4.scope("作用域") 的绑定策略。
scope的绑定策略有三种:
(1)@ :把当前属性作为字符串传值。还可以绑定来自外层scope的值,在属性值中插入{{}}即可。
(2)= :与父scope中的属性进行双向绑定。
(3)& :传递一个来自父scope的函数,稍后调用。
index.html :
1 <!doctype html>
2 <html ng-app="MyModule">
3 <head>
4 <meta charset="utf-8">
5 <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
6 </head>
7 <body>
8 <div ng-controller="MyCtrl">
9 <drink flavor="{{ctrlFlavor}}"></drink>
10 </div>
11 </body>
12 <script src="framework/angular-1.3.0.14/angular.js"></script>
13 <script src="ScopeAt.js"></script>
14 </html>
ScopeAt.js :
1 var myModule = angular.module("MyModule"
, []);
2 myModule.controller('MyCtrl', ['$scope',
function($scope){
3 $scope.ctrlFlavor="百威"
;
4 }])
5 myModule.directive("drink",
function() {
6 return {
7 restrict:'AE'
,
8 scope:{
9 flavor:'@'
10 },
11 template:"<div>{{flavor}}</div>"
12 //,
13 //link:function(scope,element,attrs){
14 // scope.flavor=attrs.flavor;
15 //}
16 }
17 });
使用link进行指令和控制器两个作用域中数据的绑定。如果用scope中@的话,就不需要link这么麻烦了,angularJS会自动进行绑定。
接下来看scope 的 ”=“ 绑定策略:
1 <div ng-controller="MyCtrl">
2 Ctrl:
3 <br>
4 <input type="text" ng-model="ctrlFlavor">
5 <br>
6 Directive:
7 <br>
8 <drink flavor="ctrlFlavor"></drink>
9 </div>
1 var myModule = angular.module("MyModule"
, []);
2 myModule.controller('MyCtrl', ['$scope',
function($scope){
3 $scope.ctrlFlavor="百威"
;
4 }])
5 myModule.directive("drink",
function() {
6 return {
7 restrict:'AE'
,
8 scope:{
9 flavor:'='
10 },
11 template:'<input type="text" ng-model="flavor"/>'
12 }
13 });
这个例子中有两个输入框,第一个绑定了MyCtrl控制器中的scope对象的ctrlFlavor 属性。第二个绑定的是指令中的flavor属性。 但是在drink 指令中 scope对象的flavor 属性 用了 ”=“ ,与父scope中的属性进行双向数据绑定。所以两个值有一个改动,另一个属性值也会改动。
最后来看一下 scope 的 ”&“ 绑定策略:
index.html :
1 <body>
2 <div ng-controller="MyCtrl">
3 <greeting greet="sayHello(name)"></greeting>
4 <greeting greet="sayHello(name)"></greeting>
5 <greeting greet="sayHello(name)"></greeting>
6 </div>
7 </body>
1 var myModule = angular.module("MyModule"
, []);
2 myModule.controller('MyCtrl', ['$scope',
function($scope){
3 $scope.sayHello=
function(name){
4 alert("Hello "+
name);
5 }
6 }])
7 myModule.directive("greeting",
function() {
8 return {
9 restrict:'AE'
,
10 scope:{
11 greet:'&'
12 },
13 template:'<input type="text" ng-model="userName" /><br/>'+
14 '<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br/>'
15 }
16 });
点击按钮 会调用greet()函数,在前面html中已经指定了greet要绑定sayHello()函数,函数的参数来绑定 ng-model 的 输入框。
4.AngularJS内置指令。
不同版本的内置指令数目不同,详细的看官方API(----api----)
http://docs.ngnice.com/api/ng/directive
5.Angular-UI。
Angular-UI (
http://angular-ui.github.io/)
复杂的指令终于结束了,Angular-UI封装了很多好的指令可以直接使用。省得自己挨个再写,费劲。关于详细的一些指令的用法,多看看API ,很好学。
希望自己越来越厉害,全能型人才即将诞生。哈哈哈哈!!
多关注博客哦
http://xinxingyu.cnblogs.com/
转载于:https://www.cnblogs.com/xinxingyu/p/4775004.html