指令是什么?    指令是我们用来扩展浏览器能力的技术之一。在DOM编译期间,和HTML关联着的指令会被检测到,并且被执行。这使得指令可以为DOM指定行为,或者改变它。

1.指令的匹配模式

index.html :
 <!doctype html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
</head>
<body>
<hello></hello>
<div hello></div>
<div class="hello"></div>
<!-- directive:hello -->
<div></div>
</body>
<script src="framework/angular-1.3.0.14/angular.js"></script>
<script src="HelloAngular_Directive.js"></script>
</html>
helloAngular_Directive.js :
 var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
return {
restrict: 'AEMC',
template: '<div>Hi everyone!</div>',
replace: true
}
});
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, 把要替换的元素内容写到一个页面里面。嗯如下所示:
 var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
return {
restrict: 'AECM',
templateUrl: 'hello.html',
replace: true
}
});


如果我们想要在别的指令中也是用这个hello.html怎么办,那么就有出现了一个缓存的解决办法。看下面的 run 方法在加载完所有模块后,只执行一次,然后把模板缓存起来,当有指令需要调用时,就调用 $templateCache.get().
 var myModule = angular.module("MyModule", []);
//注射器加载完所有模块时,此方法执行一次
myModule.run(function($templateCache){
$templateCache.put("hello.html","<div>Hello everyone!!!!!!</div>");
});
myModule.directive("hello", function($templateCache) {
return {
restrict: 'AECM',
template: $templateCache.get("hello.html"),
replace: true
}
});
 
接下来,再看一下 replace(”替换“),replace:true 会替换元素的内容。但是不想替换内容只是想添加一个内容呢,,没事,,还有 transclude 
 var myModule = angular.module("MyModule", []);
myModule.directive("hello", function() {
return {
restrict:"AE",
transclude:true,
template:"<div>Hello everyone!<div ng-transclude></div></div>"
}
});


 
最后介绍一下AngularJS的运行机制:

 
 

2.指令和控制器的交互。

index.html :
 <!doctype html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
</head>
<body>
<div ng-controller="MyCtrl">
<loader howToLoad="loadData()">滑动加载</loader>
</div>
<div ng-controller="MyCtrl2">
<loader howToLoad="loadData2()">滑动加载</loader>
</div>
</body>
<script src="framework/angular-1.3.0.14/angular.js"></script>
<script src="Directive&Controller.js"></script>
</html>

Directive&Controller.js :

 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("加载数据中...22222");
}
}]);
myModule.directive("loader", function() {
return {
restrict:"AE",
link:function(scope,element,attrs){
element.bind('mouseenter', function(event) {
//(1)scope.loadData();
//(2)scope.$apply("loadData()");
// 注意这里的坑,howToLoad会被转换成小写的howtoload
scope.$apply(attrs.howtoload);
});
}
}
});

现在我们想要实现的效果是当鼠标滑过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 :
 <!doctype html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
<script src="framework/angular-1.3.0.14/angular.js"></script>
<script src="Directive&Directive.js"></script>
</head>
<body>
<div class="row">
<div class="col-md-3">
<superman strength>动感超人---力量</superman>
</div>
</div>
<div class="row">
<div class="col-md-3">
<superman strength speed>动感超人2---力量+敏捷</superman>
</div>
</div>
<div class="row">
<div class="col-md-3">
<superman strength speed light>动感超人3---力量+敏捷+发光</superman>
</div>
</div>
</body>
</html>


Directive&Directive.js :
 var myModule = angular.module("MyModule", []);
myModule.directive("superman", function() {
return {
scope: {},//独立作用域
restrict: 'AE',
controller: function($scope) {
$scope.abilities = [];
this.addStrength = function() {
$scope.abilities.push("strength");
};
this.addSpeed = function() {
$scope.abilities.push("speed");
};
this.addLight = function() {
$scope.abilities.push("light");
};
},
link: function(scope, element, attrs) {
element.addClass('btn btn-primary');
element.bind("mouseenter", function() {
console.log(scope.abilities);
});
}
}
});
myModule.directive("strength", function() {
return {
require: '^superman',
link: function(scope, element, attrs, supermanCtrl) {
supermanCtrl.addStrength();
}
}
});
myModule.directive("speed", function() {
return {
require: '^superman',
link: function(scope, element, attrs, supermanCtrl) {
supermanCtrl.addSpeed();
}
}
});
myModule.directive("light", function() {
return {
require: '^superman',
link: function(scope, element, attrs, supermanCtrl) {
supermanCtrl.addLight();
}
}
});
定义了一个superman的指令和另外三个指令,分别是strength、speed、light、
后面三个指令都有一个 require 参数,是指都依赖superman指令,link中的最后一个参数就是superman指令的引用。
 

4.scope("作用域") 的绑定策略。

scope的绑定策略有三种:
(1)@ :把当前属性作为字符串传值。还可以绑定来自外层scope的值,在属性值中插入{{}}即可。
(2)= :与父scope中的属性进行双向绑定。
(3)& :传递一个来自父scope的函数,稍后调用。
 
index.html :
 <!doctype html>
<html ng-app="MyModule">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
</head>
<body>
<div ng-controller="MyCtrl">
<drink flavor="{{ctrlFlavor}}"></drink>
</div>
</body>
<script src="framework/angular-1.3.0.14/angular.js"></script>
<script src="ScopeAt.js"></script>
</html>

ScopeAt.js :

 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;
//}
}
});

使用link进行指令和控制器两个作用域中数据的绑定。如果用scope中@的话,就不需要link这么麻烦了,angularJS会自动进行绑定。

 
接下来看scope 的 ”=“ 绑定策略:
         <div ng-controller="MyCtrl">
Ctrl:
<br>
<input type="text" ng-model="ctrlFlavor">
<br>
Directive:
<br>
<drink flavor="ctrlFlavor"></drink>
</div>
 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"/>'
}
});

这个例子中有两个输入框,第一个绑定了MyCtrl控制器中的scope对象的ctrlFlavor 属性。第二个绑定的是指令中的flavor属性。 但是在drink 指令中 scope对象的flavor 属性 用了 ”=“ ,与父scope中的属性进行双向数据绑定。所以两个值有一个改动,另一个属性值也会改动。

 
最后来看一下 scope 的 ”&“ 绑定策略:
index.html :
     <body>
<div ng-controller="MyCtrl">
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
</div>
</body>
 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" /><br/>'+
'<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br/>'
}
});

点击按钮 会调用greet()函数,在前面html中已经指定了greet要绑定sayHello()函数,函数的参数来绑定 ng-model 的 输入框。

 

4.AngularJS内置指令。

不同版本的内置指令数目不同,详细的看官方API(----api----)
 

5.Angular-UI。

 
 
 复杂的指令终于结束了,Angular-UI封装了很多好的指令可以直接使用。省得自己挨个再写,费劲。关于详细的一些指令的用法,多看看API ,很好学。
希望自己越来越厉害,全能型人才即将诞生。哈哈哈哈!!
 
 

AngularJS开发之_指令的更多相关文章

  1. AngularJS 开发中常犯的10个错误

    简介 AngularJS是目前最为活跃的Javascript框架之一,AngularJS的目标之一是简化开发过程,这使得AngularJS非常善于构建小型app原型,但AngularJS对于全功能的客 ...

  2. AngularJS开发最常犯的10个错误

    简介 AngularJS是目前最为活跃的Javascript框架之一,AngularJS的目标之一是简化开发过程,这使得AngularJS非常善于构建小型app原型,但AngularJS对于全功能的客 ...

  3. AngularJS常用插件与指令收集

    angularjs 组件列表 bindonce UI-Router Angular Tree angular-ngSanitize模块-$sanitize服务详解 使用 AngularJS 开发一个大 ...

  4. 带你走近AngularJS - 创建自己定义指令

    带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自己定义指令 ------------ ...

  5. 带你走近AngularJS 之创建自定义指令

    带你走近AngularJS 之创建自定义指令 为什么使用AngularJS 指令? 使用过 AngularJS 的朋友应该最感兴趣的是它的指令.现今市场上的前端框架也只有AngularJS 拥有自定义 ...

  6. 20个angularjs开发工具

    AngularJS是那些渴望以动态方式来设计web app的web开发人员最偏爱的框架之一.如果你是一个希望启动AngularJS项目的开发人员,那么你可能需要帮助来挑选出趁手的工具…… 在Value ...

  7. AngularJS开发人员最常犯的10个错误

    简介AngularJS是目前最为活跃的Javascript框架之一,AngularJS的目标之一是简化开发过程,这使得AngularJS非常善于构建小型app原型,但AngularJS对于全功能的客户 ...

  8. AngularJs开发——控制器间的通信

    AngularJs开发——控制器间的通信 指令与控制器之间通信,无非是以下几种方法: 基于scope继承的方式 基于event传播的方式 service的方式 基于scope继承的方式 最简单的让控制 ...

  9. 实践分享:开始用Cordova+Ionic+AngularJS开发App

    http://www.cocoachina.com/webapp/20150707/12395.html 本文是一篇关于我本人在使用Cordova+Ionic以及AngularJS开发移动App的过程 ...

随机推荐

  1. GIT简单操作

    以下只是简单的bash的操作命令,个人比较喜欢用gui 打开 git bash here git clone https://github.com/自己的名字/trunk git checkout + ...

  2. 实现Windows Phone 8中ListBox的分页加载

    功能就是ListBox滚动到最下方的时候,能够自动加载下一页的内容. 解决问题的关键就是如何判断ListBox已经加载到了最底部. 网上找了两个解决方法: 1 http://googlers.itey ...

  3. c# 类型拷贝

    /// <summary> /// 类 名:EntityHelper /// 类 说 明:实体操作方法类 /// : /// 创建时间:2013/8/12 /// </summary ...

  4. Hibernate双向一对一对象关系模型映射

    一个员工一辆车:one-to-one 实现一:让汽车表中的外键唯一 create table emp ( eid int primary key auto_increment, ename varch ...

  5. objective-c数组

     1 #pragma mark -----------数组的初始化方式--------------  2 //        insert code here...  3 //        NSLo ...

  6. [Android Pro] 小心ReleaseByteArrayElements 中的参数问题

    referen to : http://blog.csdn.net/rainlight/article/details/818964 在Sun的官方文档中,关于该函数的用法如下 The array i ...

  7. October 4th 2016 Week 41st Tuesday

    Patience! The windmill never strays in search of the wind. 耐心等待!风车从不跑去找风. Sometimes we need to be pa ...

  8. python基础——继承和多态

    python基础——继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类 ...

  9. JAVA作业02

    一,      课堂练习 (一)构造方法 1,源代码 public class Test{ public static void main(String[] args){ Foo obj1=new F ...

  10. HTTP1.0和HTTP1.1的主要区别是

    HTTP/.0协议使用非持久连接,即在非持久连接下,一个tcp连接只传输一个Web对象 HTTP/.1默认使用持久连接(然而,HTTP/.1协议的客户机和服务器可以配置成使用非持久连接)在持久连接下, ...