带你走近AngularJS - 创建自己定义指令
带你走近AngularJS系列:
------------------------------------------------------------------------------------------------
为什么使用AngularJS 指令?
使用过 AngularJS 的朋友应该最感兴趣的是它的指令。现今市场上的前端框架也唯独AngularJS 拥有自己定义指令的功能,而且AngularJS 是眼下唯一提供Web应用可复用能力的框架。
眼下有非常多JavaScript 产品提供插件给Web开发者。比如, Bootstrap 就是当前比較流行的提供样式和JavaScript插件的前端开发工具包。可是开发者在使用Booostrap中的插件时, 必须切换到JavaScript 模式来写 jQuery 代码来激活插件尽管jQuery 代码写起来十分简单,可是必须和HTML进行同步,这是一个单调乏味且easy出错的过程。
AngularJS主页展示了一个简单的样例,用于实现Bootstrap中的 Tab功能,能够在页面中轻松加入 Tab 功能,而且用法和 ul 标签一样简单。HTML代码例如以下:
<body ng-app="components">
<h3>BootStrap Tab Component</h3>
<tabs>
<pane title="First Tab">
<div>This is the content of the first tab.</div>
</pane>
<pane title="Second Tab">
<div>This is the content of the second tab.</div>
</pane>
</tabs>
</body>
JavaScript代码例如以下:
angular.module('components', []).
directive('tabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: [ "$scope", function($scope) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
}
this.addPane = function(pane) {
if (panes.length == 0) $scope.select(pane);
panes.push(pane);
}
}],
template:
'<div class="tabbable">' +
'<ul class="nav nav-tabs">' +
'<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">'+
'<a href="" ng-click="select(pane)">{{pane.title}}</a>' +
'</li>' +
'</ul>' +
'<div class="tab-content" ng-transclude></div>' +
'</div>',
replace: true
};
}).
directive('pane', function() {
return {
require: '^tabs',
restrict: 'E',
transclude: true,
scope: { title: '@' },
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
template:
'<div class="tab-pane" ng-class="{active: selected}" ng-transclude>' +
'</div>',
replace: true
};
})
你能够从下面链接查看效果:http://jsfiddle.net/powertoolsteam/GBE7N/1/

正如你所见,除了拥实用于实现指令的 <tabs> 和<pane> 标签,页面和常规HTML页面没有什么差别。HTML开发者无需编写不论什么代码。当然,总须要有第一个吃螃蟹的人,创建指令共享使用,可是眼下Tabs指令已经非经常见了,能够在不论什么地方复用(如BootStrap,、jQueryUI、Wijmo, 和一些知名的前端插件集)。
由于指令的易用和易编写,很多用户已经開始使用AngularJS编写指令了。比如, AngularJS 开发组已经基于AngularJS实现了一系列指令-UI Bootstrap 来取代Bootstrap; 知名ComponentOne 控件厂商也在AngularJS 基础上创建了Wijmo ;我们也能够在GitHub上找到一些公共指令资料库:jQueryUI widgets。
拥有了 AngularJS,是不是认为自己已经站在了巨人的肩膀上了?可是不要高兴的太早,假设已经有了这么多的指令供我们使用,那我们为什么还要学习AngularJS ,为什么还要学习自己定义指令呢?
举个简单的样例,或许你有特殊的需求:假设你在一家財务公司工作,你须要创建一张財务表单,它须要以表格的形式展示数据、拥有绑定、编辑、校验而且同步数据更新到server的功能。表单插件非经常见可是能够满足这些详细需求的不得而知了,所以你必须依据实际业务需求来创建自己定义指令。
<body ng-app="abcFinance">
<h3>Offshore Investment Summary</h3>
<abc-investment-form
customer="currentCustomer"
country="currentCountry">
</abc-investment-form data>
</body>
这就是本篇文章的目的,接下来我们会讨论怎样创建 AngularJS指令。
创建自己定义AngularJS 指令
文章开头的自己定义指令十分的简单。它只实现了同步的功能。一般指令是包括很多其它元素的:
//创建指令模块 (或者检索现有模块)
var m = angular.module("myApp"); // 创建"my-dir"指令
myApp.directive("myDir", function() {
return {
restrict: "E", // 指令是一个元素 (并不是属性)
scope: { // 设置指令对于的scope
name: "@", // name 值传递 (字符串,单向绑定)
amount: "=", // amount 引用传递(双向绑定)
save: "&" // 保存操作
},
template: // 替换HTML (使用scope中的变量)
"<div>" +
" {{name}}: <input ng-model='amount' />" +
" <button ng-click='save()'>Save</button>" +
"</div>",
replace: true, // 使用模板替换原始标记
transclude: false, // 不复制原始HTML内容
controller: [ "$scope", function ($scope) { … }],
link: function (scope, element, attrs, controller) {…}
}
});
效果例如以下:

注意这个自己定义指令遵循一种格式:以"my" 为前缀,相似于命名空间,因此假设你在应用中引用了多个模块指令,你能够通过前缀非常easy的推断出它是在哪定义的。这不是硬性要求,可是这样做能够带来非常多便利。
指令的构造函数会返回带有属性的JavaScript 对象。这些内容在AngularJS 主页中都有清晰说明。下面是我对一些属性的理解:
- restrict: 说明指令在HTML中的应用形式,备选项有"A"、"E" 和 "C", "M" ,分别代表 attribute、element、class和comment(默认值为"A")。我们将很多其它的关注attributes-怎样创建UI元素。
- scope: 创建指令的作用范围,scope在指令中作为属性标签传递。Scope 是创建能够复用指令的必要条件,每一个指令(不论是处于嵌套指令的哪一级)都有其唯一的作用域,它不依赖于父scope。scope 对象定义names 和types 变量。上面的样例即创建了3个scope变量。
- name: "@" (值传递,单向绑定):
"@"符号表示变量是值传递。指令会检索从父级scope中传递而来字符串中的值。指令能够使用该值但无法改动,是最经常使用的变量。 - amount: "=" (引用,双向绑定)
"="符号表示变量是引用传递。指令检索主Scope中的引用取值。值能够是随意类型的,包括复合对象和数组。指令能够更改父级Scope中的值,所以当指令须要改动父级Scope中的值时我们就须要使用这样的类型。 - save: "&" (表达式)
“&”符号表示变量是在父级Scope中启作用的表达式。它同意指令实现比改动值更高级的操作。 - template: 替代原始模板中的标记的字符串。替换功能将替换全部旧元素为新值。注意template是怎样使用Scope中定义的变量的。这同意你无需写不论什么额外的代码就可以创建macro-style 风格指令。replace: 说明是否替换原始标记中的值或是追加原始标记中的值。默认值是false,这时原始标记将被保留。
- transclude: 说明自己定义指令是否复制原始标记中的内容。比如,之前展示的“tab”指令设置了transclude 为 true,由于tab 元素包括其它HTML 元素。 "dateInput" 指令则须要在初始化时为空,所以须要设置transclude 为false。
- link: 该方法在指令中扮演着重要的角色。它负责运行DOM 操作和注冊事件监听器等。link 方法包括下面參数:
- scope: 指令Scope的引用。scope 变量在初始化时是不被定义的,link 方法会注冊监视器监视值变化事件。
- element: 包括指令的DOM元素的引用, link 方法一般通过jQuery 操作实例(假设没有载入jQuery,还能够使用Angular's jqLite )。
- controller: 在有嵌套指令的情况下使用。这个參数作用在于把子指令的引用提供给父指令,同意指令之间进行交互, tab 指令就是使用该參数较典型的样例:http://jsfiddle.net/powertoolsteam/GBE7N/1/
注意,当调用link 方法时, 通过值传递("@")的scope 变量将不会被初始化,它们将会在指令的生命周期中还有一个时间点进行初始化,假设你须要监听这个事件,能够使用scope.$watch 方法。
好了,以上即为自己定义指令须要用到基本知识描写叙述。假设你仍然不熟悉指令,最好的方法就是动手实现几个小样例,能够在fiddle中进行实践:http://jsfiddle.net/powertoolsteam/Tk92U/
在下一篇文章中我们将一起熟悉几个AngularJS自己定义指令。
带你走近AngularJS - 创建自己定义指令的更多相关文章
- 带你走近AngularJS - 创建自定义指令
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...
- 带你走近AngularJS - 体验指令实例
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...
- 带你走近AngularJS - 基本功能介绍
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...
- 带你走近AngularJS 之创建自定义指令
带你走近AngularJS 之创建自定义指令 为什么使用AngularJS 指令? 使用过 AngularJS 的朋友应该最感兴趣的是它的指令.现今市场上的前端框架也只有AngularJS 拥有自定义 ...
- angularjs 创建自定义的指令
创建自定义的指令 除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTMl 元素上需要添加自定义指令名 ...
- angularjs之自己定义指令篇
1>指令基础知识 directive() 参考资料 http://www.tuicool.com/articles/aAveEj http://damoqiongqiu.iteye.com/bl ...
- 接近带给你AngularJS - 经验说明示例
接近带给你AngularJS列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自己定义指令 ------------ ...
- 你知道用AngularJs怎么定义指令吗?
前言 最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下. 欢迎批评指出错误的地方. Angularjs指令定义的API AngularJs的指令定义大致如下 ang ...
- AngularJS创建新指令 - 基本功能
指令(Directives)是所有AngularJS应用最重要的部分.尽管AngularJS已经提供了非常丰富的指令,但还是经常需要创建应用特定的指令. AngularJS原有的指令 ng-init ...
随机推荐
- JAVA wait(), notify(),sleep具体解释
在CSDN开了博客后,一直也没在上面公布过文章,直到前一段时间与一位前辈的对话,才发现技术博客的重要,立志要把CSDN的博客建好.但一直没有找到好的开篇的主题,今天再看JAVA线程相互排斥.同步的时候 ...
- SQLLoader4(数据文件中的列与表中列不一致情况-filler)
A.数据文件中字段个数少于表中列字段个数,但数据文件中缺少的列,在表定义中可以为空.----- 这种情况是比较简单的,只需要将数据文件中数据对应的列的名字写到控制文件中即可.因为SQL*Loader是 ...
- Linux远程登录
Linux远程登录 远程登录 关闭linux的防火墙 /etc/init.d/iptables stop 启动VNC服务器 Vncserver & 然后记住desktop is localho ...
- C# Datatable导出Excel方法
C# 导出Excel方法 先引用下System.IO;System.data; 具体函数如下: public static bool ExportCSV(DataTable dt, string f ...
- 如何利用 Bootstrap 进行快速 Web 开发
原文出处: IBM developerworks 了解如何使用 Bootstrap 快速开发网站和 Web 应用程序(包括移动友好型应用程序).Bootstrap 以 LESS 项目为基础,由 Twi ...
- doGet和doPost的区别
1.doGet和doPost的区别,在什么时候调用,为什么有时doPost中套用doGet 2.提交的form method=Post就执行DOPOST,否则执行GOGET 套用是不管meth ...
- K - Ignatius and the Princess IV
Description "OK, you are not too bad, em... But you can never pass the next test." ...
- shell中的退出状态码
shell中的退出状态码最大只有255,如果超过这个值,就会进行取余运算,即如果执行如下命令: exit exitCode 如果exitCode大于255,那么实际的状态码为exitCode % 25 ...
- hibernate操作数据库总结(转)
一.query方式 1.hibernate使用原生态的sql语句执行数据库查询 有些时候有些开发人员总觉得用hql语句不踏实,程序出现了错误,就猜测因为不是原生态的sql语句,数据库不支持,因此情愿选 ...
- JQuery阻止表单提交的方法总结 - 使用onsubmit()验证表单并阻止非法提交
方法1:<form onsubmit="javascript:confirm()"> 方法内返回false阻止表单提交 示例:代码检测textarea内填写的长度,未填 ...