详谈AngularJS的Directive
指令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的更多相关文章
- AngularJS之directive
AngularJS之directive AngularJS是什么就不多舌了,这里简单介绍下directive.内容基本上是读书笔记,所以如果你看过<AngularJS up and runnin ...
- Angularjs之directive指令学习笔记(二)
1.Directive的五个实例知道driective作用.其中字段restrict.template. replace.transclude.link用法 参考文章链接地址:http://damoq ...
- 前端angularJS利用directive实现移动端自定义软键盘的方法
最近公司项目的需求上要求我们iPad项目上一些需要输入数字的地方用我们自定义的软键盘而不是移动端设备自带的键盘,刚接到需求有点懵,因为之前没有做过,后来理了一下思路发现这东西也就那样.先看一下实现之后 ...
- Angularjs的directive封装ztree
一般我们做web开发都会用到树,恰好ztree为我们提供了多种风格的树插件. 接下来就看看怎么用Angularjs的directive封装ztree <!DOCTYPE html> < ...
- angularJS中directive父子组件的数据交互
angularJS中directive父子组件的数据交互 1. 使用共享 scope 的时候,可以直接从父 scope 中共享属性.使用隔离 scope 的时候,无法从父 scope 中共享属性.在 ...
- angularJS中directive与directive 之间的通信
上一篇讲了directive与controller之间的通信:但是我们directive与directive之间的通信呢? 当我们两个directive嵌套使用的时候怎么保证子directive不会被 ...
- angularJS中directive与controller之间的通信
当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...
- AngularJS之Directive,scope,$parse
AngularJS内幕详解之 Directive AngularJS内幕详解之 Scope AngularJS的指令(Directive) compile和link的区别及使用示例 浅谈Angular ...
- AngularJS中Directive指令系列 - scope属性的使用
文章是转的,我做下补充.原文地址:https://segmentfault.com/a/1190000002773689 每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部 ...
随机推荐
- struts2--上传总结(限制大小和类型 非法上传的跳转)
网上有很多版本,鉴于实践出真知的态度 我自己探索了一番 struts版本:2.3.16 限制大小: struts2默认是2M 所以如果要扩大大小限制,应该先配一个全局struts2最大上限 <c ...
- 面试Tips
面试Tips 面向对象:准备找工作的同学 内容概述:关于面试的一些经验总结,希望能带给你些许帮助.若有描述不准确的地方,欢迎指点建议. 内容提炼:共分为四阶段 1.面试前之静生慧 (1)课本知识过一遍 ...
- "数学口袋精灵"bug
首先要部署这个app项目就是第一步: 一.前提下载并安装JDK 在线图解:手把手教你安装JDK http://www.lvtao.net/server/windows-setup-jdk.h ...
- 防御 XSS 的七条原则
本文将会着重介绍防御XSS攻击的一些原则,需要读者对于XSS有所了解,至少知道XSS漏洞的基本原理,如果您对此不是特别清楚,请参考这两篇文章:<Stored and Reflected XSS ...
- LR监控tomcat服务器
采用编写VuGen脚本访问Tomcat的Status页面的方式获取性能数据(利用了关联和lr_user_data_point函数),本质上还是使用tomcat自带的监控页面,只是将监控结果加到LR的a ...
- mac下mysql5.7.10密码问题
mysql5.7.10刚安装好,会生成一个随机密码. 如果没记住这个随机密码,那么到mysql/bin/下执行mysql_secure_installation命令 按照提示重置密码和其他选项. ps ...
- 20个PHP程序性能优化的方法
1.数据库连接当使用完毕时应当关闭,不要使用长连接. 2.用@屏蔽错误消息的做法非常低效,极其低效. 3.使用选择分支语句(switch case)好于使用多个if,else if. 4.$row[' ...
- django里的http协议
一个普通的user Begin########## ['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__' ...
- Spring 中常用注解原理剖析
前言 Spring 框架核心组件之一是 IOC,IOC 则管理 Bean 的创建和 Bean 之间的依赖注入,对于 Bean 的创建可以通过在 XML 里面使用 <bean/> 标签来配置 ...
- 【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 贪心+堆
题目描述 佩内洛普是新建立的超级计算机的管理员中的一员. 她的工作是分配工作站给到这里来运行他们的计算研究任务的研究人员. 佩内洛普非常懒惰,不喜欢为到达的研究者们解锁机器. 她可以从在她的办公桌远程 ...