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