返回介绍

示例:模板控制语句 for

发布于 2024-12-24 22:41:42 字数 4974 浏览 0 评论 0 收藏 0

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();
11   
12       var link = function($scope, $ielement, $iattrs, $controller){
13   
14         var new_node = [];
15   
16         $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           }
26   
27         });
28       }
29   
30       return link;
31     }
32     return {compile: compile,
33             priority: 1000,
34             terminal: true,
35             restrict: 'E'};
36   });
37   
38   app.controller('TestCtrl', angular.noop);
39   angular.bootstrap(document, ['Demo']);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文