项目筹备近期开启Angular学习,指令比较难理解所以记录备案,推荐Angualr实战学习视频大漠穷秋 Angular实战

一、指令directive概述

指令可以对元素绑定事件监听或者改变DOM结构而使HTML拥有像jQuery一样效果具有交互性。不同于jQuery,Angular设计核心思想是通过数据与模板的绑定,
摆脱繁琐的DOM操作,而将注意力集中在业务逻辑上。

几种常见指令ng-app 指令用来指定ng的作用域是在那个标签以内部分(<html ng-app="myApp">标签) ng-repeat迭代器指令可以重复标记元素、

ng-show指令可以根据条件是否显示一个元素、ng-model指令具有双向数据绑定特性、ng-controller 用来声明一个需要和数据进行绑定的模板区域

二、自定义指令directive之模式匹配restrict

直接上代码体验一把,index.html

<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>Angular指令--自定义标签</title>
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
<hello></hello>
<div hello></div>
<div class='hello'></div>
<!-- directive:hello -->
<div></div> <!--代码模板template-->
<script type="text/ng-template" id="hello_Angular.html">
<p>Hello Angular</p>
</script>
<!--代码模板template-->
</body>
</html>

指令Directive.js

<script type="text/javascript">
//调用angular对象的module方法来声明一个模块,模块的名字和ng-app的值对应
var myModule = angular.module('myModule',[]);
/* restrict 属性值说明 <推荐使用EA>
* E--element元素 <hello></hello>
* A--attribute 属性 <div hello></div>
* C-class 样式类 <div class="hello"></div>
* M 注释 <!-- directive:hello -->
*/
//指令--对元素绑定事件监听或者改变DOM
myModule.directive('hello', function(){
return {
restrict: 'EACM',
templateUrl:'hello_Angular.html',
/*template : '<p>Hello Angular</p>',*/
replace: true
}
})
</script>

代码在线编辑  请点击这里哦

===================================================================================
restrict---匹配模式说明, 英文意思是"限制;约束;限定",这里指的是匹配我自定义的标签
===================================================================================

  • E  元素(element)   <hello></hello>
  • A  属性(attribute)  <div hello></div>
  • C  样式类(class)     <div class="hello"></div>
  • M  注释                     <!-- directive:hello -->         注意!!!空格(不常用)

温馨tips: 推荐使用EC或EA匹配模式

replace 是否替换元素的模式 replace:true浏览器DOM结构如下

replace:false 或没有replace属性时浏览器DOM结构如下

三、指令之嵌套变换transclude

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>transclude 嵌套变换</title>
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
<hello>这里是内容哦.....</hello>
<div hello>这里是内容哦hello....</div>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.directive('hello',function(){
return {
restrict: 'EA',
template: '<p>Hello World!!!<b ng-transclude></b></p>',
transclude: true, /*嵌套变换*/
replace: true /*替换*/
}
})
</script>
</body>
</html>

四、指令directive运行原理

五、指令配置参数说明

myModule.directive('namespaceDirectiveName', function factory(injectables) {
var directiveDefinitionObject = {
restrict: string,//指令的使用方式,包括标签,属性,类,注释
priority: number,//指令执行的优先级
template: string,//指令使用的模板,用HTML字符串的形式表示
templateUrl: string,//从指定的url地址加载模板或<script type="text/ng-template" id="string"></script>
replace: bool,//是否用模板替换当前元素,若为false,则append在当前元素上
transclude: bool,//是否将当前元素的内容转移到模板中
scope: bool or object,//指定指令的作用域
controller: function controllerConstructor($scope, $element, $attrs, $transclude){...},//定义与其他指令进行交互的接口函数
require: string,//指定需要依赖的其他指令 link: function postLink(scope, iElement, iAttrs) {...},//以编程的方式操作DOM,包括添加监听器等
compile: function compile(tElement, tAttrs, transclude){
return: {
pre: function preLink(scope, iElement, iAttrs, controller){...},
post: function postLink(scope, iElement, iAttrs, controller){...}
}
}//编程的方式修改DOM模板的副本,可以返回链接函数 };
return directiveDefinitionObject;
});

六、指令与控制器的交互

index.html 如下

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Directive指令与Controller控制器交互</title>
<!--引入js库anglarjs-->
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
<script type="text/javascript" src="js/Directive&Controller.js"></script>
</head>
<body>
<div ng-controller="myAppCtrl">
<loader hello howToLoad="loadData()">数据加载......</loader>
</div>
<div ng-controller="myAppCtrl2">
<loader hello howToLoad="loadData2()">数据加载2......</loader>
</div>
</body>
</html>

Directive&Controller.js

var myApp = angular.module('myApp', []);
myApp.controller('myAppCtrl', ['$scope', function($scope){
console.log($scope);
$scope.loadData = function(){
console.log('数据加载中.....');
}
}]);
myApp.controller('myAppCtrl2', ['$scope', function($scope){
console.log($scope);
$scope.loadData2 = function(){
console.log('数据加载中2.....');
}
}]);
//指令与控制器之间交互
myApp.directive('loader', function(){
return {
restrict: 'EA',
template: '<div ng-transclude></div>',
transclude: true,
replace: true,
/*scope: {}, 独立scope*/
link: function(scope, element, attrs){
element.bind('mouseenter', function(){
/*这里调用controller中的方法三种方式*/
/*(1) scope.loadData();
(2) scope.$apply('loadData()');
(3) attrs.howtoload === 属性上绑定的函数名称*/
//属性方式 注意坑!!! howtoload 得小写
scope.$apply(attrs.howtoload);
})
}
}
})

实现的效果是当鼠标滑过div元素时,调用一个加载数据的方法。

上述例子中定义了两个控制器,然后两个控制器中都使用了loader指令,并且,每个指令中都有一个参数 howToLoad .
关于指令中的 link ,上面介绍运行机制中可以了解到,link: function postLink(scope, element, attrs) {...}是用来操作dom和绑定监听事件的。
link中会有三个参数:scope(指令所属的控制器中的 $scope 对象)、element(指令所属dom元素)、attrs(dom元素所传的参数
如howToLoad 参数给的值 loadData()
然后对于如何调用所需函数,有两种方法:
1> scope.loadData() 两个控制器方法不一致时,就不能用了
2> scope.$apply() $apply()方法会从所有控制器中找到多对应的方法。这就实现了指令的复用。
明确对于控制器ng-controller都会创建属于自己独立的scope;对于指令若无scope:{}声明会继承控制器中的scope

七、指令与指令的交互

代码过长开始折叠 index.html

<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>directive指令与directive指令之间的交互</title>
<!--引入第三方样式库bootstrap.min.css-->
<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" />
<!--引入js库anglarjs-->
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
<script type="text/javascript" src="js/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',
template: '<button class="btn btn-primary" ng-transclude></button>',
transclude: true,
controller: function($scope){ /*暴露controller里面方法*/
$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, supermanCtr){
element.addClass = "btn btn-primary";
element.bind('mouseenter', function(){
console.log(scope.abilities);
})
}
}
})
myModule.directive('strength', function(){
return {
require: "^superman",/*require参数指明需要依赖的指令*/
link: function(scope, element, attrs, supermanCtr){
supermanCtr.addStrength();
}
}
});
myModule.directive('speed', function(){
return {
require: "^superman",
link: function(scope, element, attrs, supermanCtr){
supermanCtr.addSpeed();
}
}
});
myModule.directive('light', function(){
return {
require: "^superman",
link: function(scope, element, attrs, supermanCtr){
supermanCtr.addLight();
}
}
});

*require参数指明需要依赖的指令

*指令中的controller相当于暴露里面方法,便于指令复用

八、scope作用域绑定策略

scope “@” 把当前属性作为字符串传值

<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>scope绑值策略一.'@'把当前属性作为字符串传值</title>
<!--引入js库anglarjs-->
<script type="text/javascript" src="framework/1.3.0.14/angular.js"></script>
<script type="text/javascript" src="js/Scope@.js"></script>
</head>
<body>
<div ng-controller="myAppCtrl">
<drink flavor="{{ctrFlavor}}"></drink>
</div>
</body>
</html>

Scope@.js

var myModule = angular.module('myModule', []);
myModule.controller('myAppCtrl',['$scope', function($scope){
console.log($scope);
$scope.ctrFlavor = "百事可乐";
}]); myModule.directive('drink', function(){
return {
restrict: 'AE',
scope: { /*独立scope作用域*/
flavor: '@'
},
replace:true,
template: '<p>{{flavor}}</p>'
//使用link进行指令和控制器两个作用域中数据的绑定。
//如果用scope中@的话,就不需要link这么麻烦了,angularJS会自动进行绑定
/*,
link:function(scope,element,attrs){
element.bind('mouseenter', function(){
})
scope.flavor = attrs.flavor;
}*/
}
})

scope “=” 与父scope属性进行双向绑定

index.html

<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>scope绑值策略二.'='与父scope中的属性进行双向绑定</title>
<!--引入第三方样式库bootstrap.min.css-->
<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" />
<!--引入js库anglarjs-->
<script type="text/javascript" src="js/scope=.js"></script>
</head>
<body>
<div ng-controller="myModuleCtrl" class="col-sm-6">
<p>{{describe}}</p>
Ctrl--控制器:<br />
<input type="text" ng-model="ctrFlavor" class="form-control" />
<br />
<p>{{ctrFlavor}}</p>
Directive--指令:<br />
<drink flavor="ctrFlavor"></drink>
<p>{{flavor}}</p>
</div>
</body>
</html>

scope=.js

var myModule = angular.module('myModule', []);
myModule.controller('myModuleCtrl',['$scope', function($scope){
$scope.describe = "scope绑值策略二.=与父scope中的属性进行双向绑定";
$scope.ctrFlavor = "可口可乐";
}]); //=与父scope中的属性进行双向绑定
myModule.directive('drink',function(){
return {
restrict: 'EA',
scope: { /*ng-isolate-scope 隔离作用域*/
flavor : '='
},
template: '<input type="text" class="form-control" ng-model="flavor" />'
/*replace:true*/
}
}); 

这个例子中有两个输入框,第一个绑定了myModuleCtrl控制器中的scope对象的ctrlFlavor 属性。

第二个绑定的是指令中的flavor属性。但是在drink 指令中 scope对象的flavor 属性 用了 ”=“ ,

与父scope中的属性进行双向数据绑定。所以两个值有一个改动,另一个属性值也会改动。 简单理解为把两个存放数据仓库给相等 A1 == B1

scope&  '&'传递一个来自父scope的函数,稍后调用

index.html

<!DOCTYPE html>
<html ng-app="myModule">
<head>
<meta charset="UTF-8">
<title>scope绑值策略三.'&'传递一个来自父scope的函数,稍后调用</title>
<!--引入第三方样式库bootstrap.min.css-->
<link rel="stylesheet" href="framework/bootstrap-3.0.0/css/bootstrap.min.css" />
<!--引入js库anglarjs-->
<script type="text/javascript" src="js/scope&.js"></script>
</head>
<body>
<div ng-controller="myModuleCtrl">
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
<greeting greet="sayHello(name)"></greeting>
</div>
<!--代码模板template-->
<script type="text/ng-template" id="sayHello.html">
<div class="col-sm-12 container">
<form role = "form">
<div class = "form-group">
<input type="text" class="form-control" ng-model="userName" />
<button class="btn btn-primary" ng-click="greet({name:userName})">Greeting</button>
</div>
</form>
</div>
</script>
<!--代码模板template-->
</body>
</html>

scope&.js

var myModule = angular.module('myModule', []);
myModule.controller('myModuleCtrl',['$scope', function($scope){
$scope.sayHello = function(name){
console.log('Hello'+name);
}
}]);
myModule.directive('greeting', function(){
return {
restrict: 'EA',
scope: { /*'&'传递一个来自父scope的函数,稍后调用*/
greet : '&'
},
templateUrl: 'sayHello.html'
}
});

以上所有代码汇总下载请点击

【资料参考】

http://www.cnblogs.com/lvdabao/tag/AngularJs/

http://angularjs.cn/T001

Angular之指令Directive系列的更多相关文章

  1. angular 自定义指令 directive transclude 理解

    项目中断断续续的用了下angular,也没狠下心 认真的学习.angular 特别是自定义指令这块 空白. transclude 定义是否将当前元素的内容转移到模板中.看解释有点抽象. 看解释有点抽象 ...

  2. Angular自定义指令directive:scope属性

    在AngularJS中,除了内置指令如ng-click等,我们还可以自定义指令.自定义指令,是为了扩展DOM元素的功能.代码中,通过指定directive中的restrict属性,来决定这个指令是作为 ...

  3. Angular入门到精通系列教程(10)- 指令(Directive)

    1. 摘要 2. 组件与指令之间的关系 2.1. 指令的种类 3. Angular 中指令的用途 4. 指令举例 4.1. 指令功能 4.2. Anuglar CLI生成基本文件 4.3. Direc ...

  4. Angular自定义指令(directive)

    angular自定义指令,意我们可以通过angula自己定义指令,来实现我们的特殊要求,为所欲为,一支穿云箭,千军万马来相见 多少年的老规矩了,先看代码: <!DOCTYPE html> ...

  5. angular 自定义指令详解 Directive

    在angular中,Directive,自定义指令的学习,可以更好的理解angular指令的原理,当angular的指令不能满足你的需求的时候,嘿嘿,你就可以来看看这篇文章,自定义自己的指令,可以满足 ...

  6. -_-#【Angular】自定义指令directive

    AngularJS学习笔记 <!DOCTYPE html> <html ng-app="Demo"> <head> <meta chars ...

  7. Angular学习-指令入门

    1.指令的定义 从用户的角度来看,指令就是在应用的模板中使用的自定义HTML标签.指令可以很简单,也可以很复杂.AngularJS的HTML编译器会解析指令,增强模板的功能.也是组件化未来的发展趋势, ...

  8. angular js 指令的数据传递 及作用域数据绑定

    <div my-directive my-url="http://google.com" my-link-text="Click me to go to Googl ...

  9. angular自定义指令详解

    指令(directive)是angular里面最核心也是最难懂的东西,在慕课网看了下大漠穷秋老湿的视频,自己百度半天做了一些小test,总算把一切都搞明白了. 先列出学习来源: 指令中controll ...

随机推荐

  1. 在你的网站实现qq登陆(php)

    这个qq的oauth2.1有个坑,坑了我半天,后来查了不少资料总算弄通了,现在把详细步骤记录下来. 步骤一.登陆http://connect.qq.com/     步骤二.创建应用.我创建的是wen ...

  2. shell命令输入输出重定向

    Linux命令的执行过程 首先是输入:stdin输入可以从键盘,也可以从文件得到 命令执行完成:把成功结果输出到屏幕,stout默认是屏幕 命令执行有错误:把错误也输出到屏幕上面,stderr默认也是 ...

  3. 万能日志数据收集器 Fluentd - 每天5分钟玩转 Docker 容器技术(91)

    前面的 ELK 中我们是用 Filebeat 收集 Docker 容器的日志,利用的是 Docker 默认的 logging driver json-file,本节我们将使用 fluentd 来收集容 ...

  4. BZOJ-2330-[SCOI2011]糖果(差分约束)

    Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的 ...

  5. linux数据库备份脚本

    数据库备份1.创建个备份存储目录mkdir /root/backup/2.以下内容写到dbbackup.sh(注意,使用VIM 或者VI命令新建文件,不要在WINDOWS下新建,否则可能提示 No s ...

  6. threejs 组成的3d管道,寻最短路径问题

    threejs 里面的3d管道的每个节点ID是唯一的,且对应x,y,z坐标.那么当需要从A点到B点的时候,可能出现有多条路径可走,此时便需要求出最短行走路径,因此用到一个寻路径算法.我们将问题简化如下 ...

  7. Scrum Meeting Alpha - 5

    Scrum Meeting Alpha - 5 NewTeam 2017/10/20 地点:主楼与4号楼之间的走廊2楼 任务反馈 团队成员 完成任务 计划任务 安万贺 完成了对班级作业部分的API的包 ...

  8. RabbitMQ之工作队列

    工作队列 工作队列(又称:任务队列Task Queues)是为了避免等待一些占用大量资源.时间的操作,当我们把任务Task当做消息发送队列中,一个运行在后台的工作者worker进程就会取出任务然后处理 ...

  9. Android内存泄露的原因

    (一)释放对象的引用,误将一个本来生命周期短的对象存放到一个生命周期相对较长的对象中,也称“对象游离“.隐蔽的内部类(Anonymous Inner Class): mHandler = new Ha ...

  10. [转] 深刻理解Python中的元类(metaclass)

    非常详细的一篇深入讲解Python中metaclass的文章,感谢伯乐在线-bigship翻译及作者,转载收藏. 本文由 伯乐在线 - bigship 翻译.未经许可,禁止转载!英文出处:stacko ...