指令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. Oracle win64_12g 安装

    1.Oracle win64_12g 安装 1.下载安装包:这里需要自己注册一下,然后就可以登录下载软件了. 下载地址: http://www.oracle.com/technetwork/datab ...

  2. Java 线程安全问题

    线程安全问题产生原因: 1.多个线程操作共享的数据: 2.操作共享数据的线程代码有多条.   当一个线程正在执行操作共享数据的多条代码过程中,其它线程也参与了运算, 就会导致线程安全问题的发生. cl ...

  3. 敏捷冲刺DAY8

    一. 每日会议 1. 照片 2. 昨日完成工作 第一次阶段测试. 3. 今日完成工作 对前七次敏捷冲刺的工作进行完善. 4. 工作中遇到的困难 浏览器兼容性问题.页面响应性能问题.内存溢出问题-- 二 ...

  4. C#控件之Repeater控件使用

    歡迎大家來討論,修改,一定虛心接受. 1.為什麼使用Repeater控件? 關於把從數據庫讀取的數據綁定到前台頁面,我們可以使用DataGrid.DataGridView以及Repeater來佈局,三 ...

  5. 【beta】nice!-------约吧NABCD

    小组名称:nice! 组长:李权 成员:于淼  刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 约吧APP下载地址: 百度云:链接:http://pan.baidu.com/s/1jHNBR3g ...

  6. PAT L1-017 到底有多二

    https://pintia.cn/problem-sets/994805046380707840/problems/994805121500692480 一个整数“犯二的程度”定义为该数字中包含2的 ...

  7. python基础(一)简单入门

    一.第一个python程序 1.交互式编程 直接在命令行里面输入python即可进入python交互式命令行,linux下一样: 在 python 提示符中输入以下文本信息,然后按 Enter 键查看 ...

  8. c#中,字符串前加@是什么意思

    让转移字符"\"保持原意,不要转义,如一个地址字符串string path="c:\abc\";默认的"\"是作为转义来使用的,而不是一个真 ...

  9. jquery弹出层开源框架layer

    高度自适应参考:layer.open如何让高度自适应? 高度自适应修改layer.js代码如下: r.iframeAuto = function(e) { if (e) { var t = r.get ...

  10. UVA11736_Debugging RAM

    题目绝对够水,我就不详细说明了. 直接上代码吧.只是提示一下要用 unsigned long long. (不知道我不用字典树为什么会超时,肿么搞的) #include <iostream> ...