### 18.3. 基本的自定义方法
自定义一个指令可以非常非常的复杂,但是其基本的调用形式,同自定义服务大概是相同的:
<p show style="font-size: 12px;"></p>
<script type="text/javascript">
var app = angular.module('Demo', [], angular.noop);
app.directive('show', function(){
var func = function($scope, $element, $attrs){
console.log($scope);
console.log($element);
console.log($attrs);
} return func;
//return {compile: function(){return func}}
});
angular.bootstrap(document, ['Demo']);
</script>
如果在 `directive` 中直接返回一个函数,则这个函数会作为 `compile` 的返回值,也即是作为 `link` 函数使用。这里说的 `compile` 和 `link` 都是一个指令的组成部分,一个完整的定义应该返回一个对象,这个对象包括了多个属性:
- name
- priority
- terminal
- scope
- controller
- require
- restrict
- template
- templateUrl
- replace
- transclude
- compile
- link
上面的每一个属性,都可以单独探讨的。
下面是一个完整的基本的指令定义例子:
<code lines>
//失去焦点使用 jQuery 的扩展支持冒泡
app.directive('ngBlur', function($parse){
return function($scope, $element, $attr){
var fn = $parse($attr['ngBlur']);
$element.on('focusout', function(event){
fn($scope, {$event: event});
});
}
});
</code>
<div code lines>
//失去焦点使用 jQuery 的扩展支持冒泡
app.directive('ngBlur', function($parse){
return function($scope, $element, $attr){
var fn = $parse($attr['ngBlur']);
$element.on('focusout', function(event){
fn($scope, {$event: event});
});
}
});
</div>
1 var app = angular.module('Demo', [], angular.noop);
2 3 app.directive('code', function(){
4 var func = function($scope, $element, $attrs){
5 6 var html = $element.text();
7 var lines = html.split('\n');
8 9 //处理首尾空白
10 if(lines[0] == ''){lines = lines.slice(1, lines.length - 1)}
11 if(lines[lines.length-1] == ''){lines = lines.slice(0, lines.length - 1)}
1213 $element.empty();
1415 //处理外框
16 (function(){
17 $element.css('clear', 'both');
18 $element.css('display', 'block');
19 $element.css('line-height', '20px');
20 $element.css('height', '200px');
21 })();
2223 //是否显示行号的选项
24 if('lines' in $attrs){
25 //处理行号
26 (function(){
27 var div = $('<div style="width: %spx; background-color: gray; float: left; text-align: right; padding-right: 5px; margin-right: 10px;"></div>'
28 .replace('%s', String(lines.length).length * 10));
29 var s = '';
30 angular.forEach(lines, function(_, i){
31 s += '<pre style="margin: 0;">%s</pre>\n'.replace('%s', i + 1);
32 });
33 div.html(s);
34 $element.append(div);
35 })();
36 }
3738 //处理内容
39 (function(){
40 var div = $('<div style="float: left;"></div>');
41 var s = '';
42 angular.forEach(lines, function(l){
43 s += '<span style="margin: 0;">%s</span><br />\n'.replace('%s', l.replace(/\s/g, '<span> </span>'));
44 });
45 div.html(s);
46 $element.append(div);
47 })();
48 }
4950 return {link: func,
51 restrict: 'AE'}; //以元素或属性的形式使用命令
52 });
5354 angular.bootstrap(document, ['Demo']);
上面这个自定义的指令,做的事情就是解析节点中的文本内容,然后修改它,再把生成的新内容填充到节点当中去。其间还涉及了节点属性值 `lines` 的处理。这算是指令中最简单的一种形式。因为它是“一次性使用”,中间没有变量的处理。比如如果节点原来的文本内容是一个变量引用,类似于 `{{ code }}` ,那上面的代码就不行了。这种情况麻烦得多。后面会讨论。
- Introduction
- 关于AngularJS
- 关于本文档
- 开始的例子
- 依赖注入
- 作用域
- 数据绑定与模板
- 数据->模板
- 模板->数据
- 数据->模板->数据->模板
- 模板
- 定义模板内容
- 内容渲染控制
- 节点控制
- 事件绑定
- 表单控件
- 模板中的过滤器
- 排序 orderBy
- 过滤列表 filter
- 其它
- 例子:表头排序
- 例子:搜索
- 锚点路由
- 路由定义
- 参数定义
- 业务处理
- 定义模板变量标识标签
- AJAX
- HTTP请求
- 广义回调管理
- 工具函数
- 上下文绑定
- 对象处理
- 类型判定
- 其它服务
- 日志
- 缓存
- 计时器
- 表达式函数化
- 模板单独使用
- 自定义模块和服务
- 模块和服务的概念与关系
- 定义模块
- 定义服务
- 引入模块并使用服务
- 附加模块 ngResource
- 使用引入与整体概念
- 基本定义
- 基本使用
- 定义和使用时的占位量
- 实例
- AngularJS与其它框架的混用(jQuery, Dojo)
- 自定义过滤器
- 自定义指令directive
- 指令的使用
- 指令的执行过程
- 基本的自定义方法
- 属性值类型的自定义
- Compile的细节
- transclude的细节
- 把节点内容作为变量处理的类型
- 指令定义时的参数
- Attributes的细节
- 预定义的 NgModelController
- 预定义的 FormController
- 示例:文本框
- 示例:模板控制语句 for
- 示例:模板控制语句 if/else