指令是什么?    指令是我们用来扩展浏览器能力的技术之一。在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. js 中 toString( ) 和valueOf( )

    1.toString()方法:主要用于Array.Boolean.Date.Error.Function.Number等对象转化为字符串形式.日期类的toString()方法返回一个可读的日期和字符串 ...

  2. JavaScript高级程序设计学习笔记--引用类型

    Object类型 对象字面量表示法: var person={ name:"Nicholas", age:29, 5:true }; 这人例子会创建一个对象,包含三个属性:name ...

  3. android中判断网络连接是否可用

    一.判断网络连接是否可用 public static boolean isNetworkAvailable(Context context) { ConnectivityManager cm = (C ...

  4. UIView CALayer 的区别

    UIView与CALayer的区别,很详细 研究Core Animation已经有段时间了,关于Core Animation,网上没什么好的介绍.苹果网站上有篇专门的总结性介绍,但是似乎原理性的东西不 ...

  5. JDBC题库

    一.    填空题 JDBC    ,是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问.它由一组用Java语言编写的类和接口组成. JDBC API:供程序员调用的接口与类,集 ...

  6. September 19th 2016 Week 39th Monday

    We come nearest to the great when we are great in humility. 我们最为谦逊的时候越接近伟大. When you are powerful en ...

  7. Loadrunner11.0 录制手机App脚本的方法

    使用Loadrunner录制手机终端App脚本 1. 说明 目前手机APP上的功能日益丰富,对手机应用功能的性能测试需求也越来越多.公司比较抠门没有花钱买Loadrunner,可怜我们工作中一直用的破 ...

  8. 利用drozer进行Android渗透测试

    一.安装与启动 1. 安装 第一步:从 http://mwr.to/drozer 下载Drozer (Windows Installer) 第二步:在 Android 设备中安装 agent.apk ...

  9. 一般处理程序获取session值

    1.要在一般处理程序中获取其他页面的session值,需要引用名空间: using System.Web.SessionState; 2.然后继承一个接口:IRequiresSessionState, ...

  10. Arch Linux Installation Guide

    Arch Linux Installation Guide   timedatectl set-ntp true   sed -i '/Score/{/China/!{n;s/^/#/}}' /etc ...