### 18.13. 示例:模板控制語句 for
這個示例嘗試實現一個重復語句,功能同官方的 `ngRepeat` ,但是使用方式類似于我們通常編程語言中的 _for_ 語句:
<div ng-controller="TestCtrl" ng-init="obj_list=[1,2,3,4]; name='name'">
<ul>
<for o in obj_list>
<li>{{ o }}, {{ name }}</li>
</for>
</ul>
<button ng-click="obj_list=[1,2]; name='o?'">修改</button>
</div>
同樣,我們從上面的使用方式去考慮這個指令的實現:
- 這是一個完全的控制指令,所以單個節點應該只有它一個指令起作用就好了,于是權重要比較高,并且“到此為止”—— _priority_ 設置為 `1000` , _terminal_ 設置為 `true` 。
- 使用時的語法問題。事實上瀏覽器會把 `for` 節點補充成一個正確的 HTML 結構,即里面的屬性都會變成類似 `o=""` 這樣。我們通過節點的 `outerHTML` 屬性取到字符串并解析取得需要的信息。
- 我們把 `for` 節點之間的內容作為一個模板,并且通過循環多次渲染該模板之后把結果填充到合適的位置。
- 在處理上面的那個模板時,需要不斷地創建新 `scope` 的,并且 `o` 這個成員需要單獨賦值。
注意:這里只是簡單實現功能。官方的那個 _ngRepeat_ 比較復雜,是做了專門的算法優化的。當然,這里的實現也可以是簡單把 DOM 結構變成使用 _ngRepeat_ 的形式 :)
JS 部分代碼:
1 var app = angular.module('Demo', [], angular.noop);
2 3 app.directive('for', function($compile){
4 var compile = function($element, $attrs, $link){
5 var match = $element[0].outerHTML.match('<for (.?)=.? in=.? (.?)=.*?>');
6 if(!match || match.length != 3){throw Error('syntax: <for o in obj_list>')}
7 var iter = match[1];
8 var list = match[2];
9 var tpl = $compile($.trim($element.html()));
10 $element.empty();
1112 var link = function($scope, $ielement, $iattrs, $controller){
1314 var new_node = [];
1516 $scope.$watch(list, function(list){
17 angular.forEach(new_node, function(n){n.remove()});
18 var scp, inode;
19 for(var i = 0, ii = list.length; i < ii; i++){
20 scp = $scope.$new();
21 scp[iter] = list[i];
22 inode = tpl(scp, angular.noop);
23 $ielement.before(inode);
24 new_node.push(inode);
25 }
2627 });
28 }
2930 return link;
31 }
32 return {compile: compile,
33 priority: 1000,
34 terminal: true,
35 restrict: 'E'};
36 });
3738 app.controller('TestCtrl', angular.noop);
39 angular.bootstrap(document, ['Demo']);
- Introduction
- 關于AngularJS
- 關于本文檔
- 開始的例子
- 依賴注入
- 作用域
- 數據綁定與模板
- 數據->模板
- 模板->數據
- 數據->模板->數據->模板
- 模板
- 定義模板內容
- 內容渲染控制
- 節點控制
- 事件綁定
- 表單控件
- 模板中的過濾器
- 排序 orderBy
- 過濾列表 filter
- 其它
- 例子:表頭排序
- 例子:搜索
- 錨點路由
- 路由定義
- 參數定義
- 業務處理
- 定義模板變量標識標簽
- AJAX
- HTTP請求
- 廣義回調管理
- 工具函數
- 上下文綁定
- 對象處理
- 類型判定
- 其它服務
- 日志
- 緩存
- 計時器
- 表達式函數化
- 模板單獨使用
- 自定義模塊和服務
- 模塊和服務的概念與關系
- 定義模塊
- 定義服務
- 引入模塊并使用服務
- 附加模塊 ngResource
- 使用引入與整體概念
- 基本定義
- 基本使用
- 定義和使用時的占位量
- 實例
- AngularJS與其它框架的混用(jQuery, Dojo)
- 自定義過濾器
- 自定義指令directive
- 指令的使用
- 指令的執行過程
- 基本的自定義方法
- 屬性值類型的自定義
- Compile的細節
- transclude的細節
- 把節點內容作為變量處理的類型
- 指令定義時的參數
- Attributes的細節
- 預定義的 NgModelController
- 預定義的 FormController
- 示例:文本框
- 示例:模板控制語句 for
- 示例:模板控制語句 if/else