### 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