指令Directive是AngularJS最重要的核心。我用AngularJS用的并不是很深,一直以来也是在使用中摸索,从一开始的什么都不懂,查不到系统的资料,到开始使用一些简单的数据绑定{{}},到发现ng-bind比双括弧好用是因为DOM加载速度的问题,到发现简单的ng-repeat能完成很多事情,到用它来做表单验证时发现ng-form好好用,到... 总之,对AngularJS从无知到有一定认可的现在,我觉得我使用它最大的好处就是数据绑定,将数据绑定在$scope里面然后想怎么写就怎么写。除此之外,使用AngularJS也让我慢慢理解组件化开发的概念,我也越来越倾向于使用这样的方式去开发,更加赞同这样的理念。

然而直到目前为止,我仍然停留在使用一些简单的数据绑定的层次中,虽然数据绑定是angularJS的一大核心,但是如果不掌握Directive,实现自己的依赖注入,是不能完全发挥出AngularJS的功效的,AngularJS最终的功效是自定义的模块化组件式开发,这里面的自定义,就是由Directive来实现的,所以,我觉得有必要专门用一篇博客来记录我对Directive的学习过程。

什么是指令?

我对指令的肤浅理解就是我们用的HTML标签,我们平时写一些原生HTML经常会发现满足不了需求,所谓自定义指令其实可以理解为自定义标签。据我现在的manager说他以前在一个上十个人的team中,一个项目下来得有上百个directive。那么我的理解是,directive,从标签的角度上来说封装了原生的HTML,从数据的角度上来说实现了数据绑定并且封装了ajax,它让一个自定义的标签有了集成的HTML功能,并且可以和动态的数据进行交互。可能还没有理解到位,可能还没有完全体会到Directive的精妙,但是怎么说呢?我目前就能够用到这些,简单的东西对我的帮助也是巨大的,从现实的角度上来说,用不上的,就是没有用的,从项目的角度上来讲,要从需求出发,而不应该从技术难度出发,先用起来再去学习,能用多少学多少,用完了再把剩下的想学多少学多少,而不是先学完了再去用。

上面说的还比较复杂,举个简单的例子吧,我们以前经常这样写HTML

<div>
<span>一点点内容</span>
</div>

现在我们可以这么写了

<tabpanel>
<panel>子面板1</panel>
<panel>子面板2</panel>
</tabpanel>

这样写肯定会有问题,因为当浏览器看到这些标签的时候,它心里肯定会想,这是什么鬼?不过在你用directive对这些标签做过解释之后,浏览器就能认得它们了,这就是Directive。

Hello,World!

这是我刚开始学习AngularJS的时候看到的一个Directive的示例,我喜欢简洁的Test风格的代码,就像"Hello,World!"那样,不管学什么东西,先尝试着对这个东西say hello,先用它来说话,我觉得这是一种很好的习惯。

module.directive( "directive_name", [ 'JSONObject', function( JSONObject ) {
return {
restrict: "A",
link: function(scope , element , attrs) {
element.bind( "click", function() {
//directive code
});
}
}
}]);

我至今还没有搞清楚这个JSONObject是怎么个道理注入到directive的function作为参数的,虽然我不知道,但是这貌似不重要,因为我还见过这样的形式:

app.directive('autocomplete', function () {
return {
restrict: 'EA',
replace : true,
transclude : true,
template: autocompleteTpl,
link: function (scope, element, attr) { }
}
});

化繁为简以后我们就可以更加专注于那些本应该是最开始的事情上了。很显然,这段代码的主体部分是return的返回值,它返回了一个Object,我并不能知道这些键值对是什么,我打算去了解它,而且,感觉没什么用的我暂时不去理会,我没有义务去把一个框架的参数表给背下来,东西是用出来的,不是记出来的,更何况是别人写的框架,别人的东西。

好吧!它还不是最简单的,最简单的应该是这个样子的

var appModule = angular.module('app', []);
appModule.directive('hello', function() {
return {
restrict: 'E',
template: '<div>Hi there</div>',
replace: true
};
});

先说下restrict,它说明了我们的指令的类型,一共有4种,E是Element,A是Attribute,C是Class,M是Comment,一看就明白,看不明白还可以看图

注意一下,我们一般不用后两种,就是C和M,不用C的主要原因是因为MVC的思维,尽可能地不要让JS代码污染CSS。

template是我们要替换指令的内容,就是HTML的模板。

replace控制了替换的开关,当它为false的时候,template不会去替换指令,我们一般设置成true。

Transclude

如果我们需要替换的HTML标签很长,显然不能用 拼接字符串的方式来写,这时候我们可以用templateUrl来替代template,从而可以把模板写到一个独立的HTML文件中。

var appModule = angular.module('app', []);
appModule.directive('hello', function() {
return {
restrict: 'E',
template: '<div>Hi there <span ng-transclude></span></div>',
transclude: true
};
});

transclude的作用是用我们规定的template去替换我们自定义的指令标签并且template内部的结构(子标签)保持不变。

Compile&Link

当我们需要把某些事情绑定到某个元素上,我们就需要提供一个link函数

var expanderModule=angular.module('expanderModule', [])
expanderModule.directive('expander', function() {
return {
restrict : 'EA',
replace : true,
transclude : true,
scope : {
title : '=expanderTitle'
},
template : '<div>'
+ '<div class="title" ng-click="toggle()">{{title}}</div>'
+ '<div class="body" ng-show="showMe" ng-transclude></div>'
+ '</div>',
link : function(scope, element, attrs) {
scope.showMe = false;
scope.toggle = function toggle() {
scope.showMe = !scope.showMe;
}
}
}
});
expanderModule.controller('SomeController',function($scope) {
$scope.title = '点击展开';
$scope.text = '这里是内部的内容。';
});

HTML

<html ng-app='expanderModule'>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="angular.min.js"></script>
<link rel="stylesheet" type="text/css" href="ExpanderSimple.css"/>
</head>
<body>
<div ng-controller='SomeController'>
<expander class='expander' expander-title='title'>
{{text}}
</expander>
</div>
</body>
<script src="ExpanderSimple.js"></script>
</html>

Template可以是一个函数

这个函数可以接收两个参数,一个是tElements,一个是tAttrs

其中tElement是指使用此指令的元素,而tAttrs则实例的属性,它是一个由元素上所有的属性组成的集合(对象)形如

{title:'title', name:'Larry'}

当template是一个函数的时候

angular.module("app",[]).directive("directitle",function(){
return{
restrict:'EAC',
template: function(tElement,tAttrs){
var _html = '';
_html += '<div>'+tAttrs.title+'</div>';
return _html;
}
};
})

这个时候我们可以在HTML里愉快的设置属性,结果就会有对应的变化,比如这样

<directitle title='hello'></directitle>

结果就会变成

<div>hello</div>

===============2016年3月1日================

1.restrict
E: 表示该directive仅能以element方式使用,即:<my-dialog></my-dialog>
A: 表示该directive仅能以attribute方式使用,即:<div my-dialog></div>
EA: 表示该directive既能以element方式使用,也能以attribute方式使用

2.transclude
你的directive可能接受页面上的其他html内容时才会用到,建议先去掉该参数。有些高阶了。

3.scope
当你写上该属性时,就表示这个directive不会从它的controller里继承$scope对象,而是会重新创建一个。

4.templateUrl
你的directive里的html内容

5.link
可以简单理解为,当directive被angular 编译后,执行该方法

element简单说就是$('directive')

attrs是个map,内容是你这个directive上的所有属性,假如在页面上这样写一个directive:

<my-dialog type="modal" animation="fade"></my-dialog>

那attrs就是:

{
type: 'modal',
animation: 'fade'
}

文章来源:

http://damoqiongqiu.iteye.com/blog/1917971

http://my.oschina.net/ilivebox/blog/289670

详谈AngularJS的Directive的更多相关文章

  1. AngularJS之directive

    AngularJS之directive AngularJS是什么就不多舌了,这里简单介绍下directive.内容基本上是读书笔记,所以如果你看过<AngularJS up and runnin ...

  2. Angularjs之directive指令学习笔记(二)

    1.Directive的五个实例知道driective作用.其中字段restrict.template. replace.transclude.link用法 参考文章链接地址:http://damoq ...

  3. 前端angularJS利用directive实现移动端自定义软键盘的方法

    最近公司项目的需求上要求我们iPad项目上一些需要输入数字的地方用我们自定义的软键盘而不是移动端设备自带的键盘,刚接到需求有点懵,因为之前没有做过,后来理了一下思路发现这东西也就那样.先看一下实现之后 ...

  4. Angularjs的directive封装ztree

    一般我们做web开发都会用到树,恰好ztree为我们提供了多种风格的树插件. 接下来就看看怎么用Angularjs的directive封装ztree <!DOCTYPE html> < ...

  5. angularJS中directive父子组件的数据交互

    angularJS中directive父子组件的数据交互 1. 使用共享 scope 的时候,可以直接从父 scope 中共享属性.使用隔离 scope 的时候,无法从父 scope 中共享属性.在 ...

  6. angularJS中directive与directive 之间的通信

    上一篇讲了directive与controller之间的通信:但是我们directive与directive之间的通信呢? 当我们两个directive嵌套使用的时候怎么保证子directive不会被 ...

  7. angularJS中directive与controller之间的通信

    当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...

  8. AngularJS之Directive,scope,$parse

    AngularJS内幕详解之 Directive AngularJS内幕详解之 Scope AngularJS的指令(Directive) compile和link的区别及使用示例 浅谈Angular ...

  9. AngularJS中Directive指令系列 - scope属性的使用

    文章是转的,我做下补充.原文地址:https://segmentfault.com/a/1190000002773689 每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部 ...

随机推荐

  1. lintcode-439-线段树的构造 II

    439-线段树的构造 II 线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间.start和end都是整数,并按照如下的方式赋值: 根节点的 start ...

  2. size和STL中的size_type

    为了使自己的程序有很好的移植性,c++程序员应该尽量使用size_t和size_type而不是int, unsigned 1. size_t是全局定义的类型:size_type是STL类中定义的类型属 ...

  3. 目标跟踪之Lukas-Kanade光流法(转)

    光流是图像亮度的运动信息描述.光流法计算最初是由Horn和Schunck于1981年提出的,创造性地将二维速度场与灰度相联系,引入光流约束方程,得到光流计算的基本算法.光流计算基于物体移动的光学特性提 ...

  4. 软工实践团队展示——WorldElite

    软工实践团队展示--WorldElite 本次作业链接 团队成员 031602636许舒玲(组长) 031602237吴杰婷 031602634吴志鸿 081600107傅滨 031602220雷博浩 ...

  5. 小记IptabLes和IptabLex病毒清理过程

    去年有台Linux服务器被黑了,看了500万行日志(现在觉得当时好厉害呀),反正当时的日志文件有700Mb以上大.前两天师兄告诉我,信息中心的老师给他说我们有台服务器应该是被人入侵了,当作内网的跳板, ...

  6. Android内存泄漏第二课--------(集合中对象没清理造成的内存泄漏 )

    一.我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大.如果这个集合是static的话,那情况就更严重 ...

  7. 点击除指定元素以外的任意地方隐藏js

    $(document).click(function () { $(".search_box").hide(); }); $(".resultUl").on(& ...

  8. TCP的拥塞控制 (三)

    1.   Multiple Packet Losses Fast Retransmit/Fast Recovery机制可以很好地处理单个packet丢失的问题,但当大量packet同时丢包时(一个RT ...

  9. Tajo--一个分布式数据仓库系统(设计架构)

    上一篇Tajo--一个分布式数据仓库系统(概述)废话了一通,下面介绍一下Tajo的体系结构.以及官方的实验成果吧 一.体系架构 Tajo采用了Master-Worker架构(下图虚线框目前还在计划中) ...

  10. HiHoCoder1513:小Hi的烦恼——题解

    https://hihocoder.com/problemset/problem/1513 小Hi从小的一大兴趣爱好就是学习,但是他发现尽管他认真学习,依旧有学神考的比他好. 小Hi在高中期间参加了市 ...