hjzheng / CUF_meeting_knowledge_share

Record CUF team meeting knowledge share
121 stars 49 forks source link

2015-4-14 angular实现ng-repeat递归 #29

Open hjzheng opened 9 years ago

hjzheng commented 9 years ago

AngularJS recursive templates

http://benfoster.io/blog/angularjs-recursive-templates http://www.cnblogs.com/kuangliu/p/4146705.html

工作中我们经常要遍历多层数据,如果数据是已知层级的话,用 ng-repeat 就搞定了,要是数据深度是无限的呢,或者我们要实现一个无限层级的 tree 的时候,该怎么办? 答案是使用 ng-include 指令递归模板

Example

HTML

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="../../vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="../../vendor/bootstrap/css/bootstrap-theme.min.css" rel="stylesheet"/>
</head>
<body ng-app>
   <div ng-controller="treeController" class="container">
       <div class="row">
           <h2>ng-repeat recursive list example</h2>
           <ul>
               <li ng-repeat="item in tree" ng-include="'treeItem'"></li>
           </ul>
       </div>
   </div>

    <script src="../../vendor/angularjs/angularjs.js"></script>
    <script src="treeList.js"></script>
    <script type="text/ng-template" id="treeItem">
        {{item.id}} --- {{item.name}}
        <ul ng-if="item.children">
           <li ng-repeat="item in item.children" ng-include="'treeItem'">
           </li>
       </ul>
    </script>
</body>
</html>

treeList.js

/**
 * Created by hjzheng on 2014/10/27.
 */
var treeController = function ($scope) {
    $scope.tree = [
        { id: 1, name: 'John', score: 130, city: 'New York', birthday: '1980/2/5',
            children:[
                { id: 6, name: 'John2', score: 82, city: 'San Fran1', birthday: '1990/1/21'},
                { id: 7, name: 'John2', score: 81, city: 'San Fran2', birthday: '1990/1/22',
                    children:[{ id: 8, name: 'John3', score: 89, 
                                               city: 'San Francisco', birthday: '1990/1/21'}]
                }
            ]
        },
        { id: 2, name: 'Alice', score: 123, city: 'Washington', birthday: '1984/3/7'},
        { id: 3, name: 'Lee', score: 149, city: 'Shanghai', birthday: '1986/10/8'},
        { id: 4, name: 'Mike', score: 100, city: 'London', birthday: '1988/8/12'},
        { id: 5, name: 'Tom', score: 89, city: 'San Francisco', birthday: '1990/1/21',
            children: [
               { id: 9, name: 'Tom1', score: 77, city: 'San Francisco', birthday: '1990/1/21'},
               { id: 10, name: 'Tom2', score: 85, city: 'San Francisco', birthday: '1990/1/21'},
               { id: 11, name: 'Tom3', score: 83, city: 'San Francisco', birthday: '1990/1/21'}
            ]
        }
    ];
}

Angular Tree Grid(自己实现)

通过Angular自定义Filter,实现复杂Tree数据遍历(复杂数据参见上面的例子)和过滤(对expend数据过滤) Example: http://jsfiddle.net/hjzheng/78jz0mrL/ (翻墙)

hjzheng commented 9 years ago

关于Angular Tree Grid增加排序和search功能后的问题 Error: [$rootScope:infdig] Example: http://stackoverflow.com/questions/29738628/error-rootscopeinfdig-when-i-sorted-my-angular-tree-table-example

//解决思路: 因为filter较容易引发性能问题,源于其处理机制,一个filter至少会执行两次以上,即使只是对单条数据做过滤,这个可以参考这篇文章: http://www.bennadel.com/blog/2489-how-often-do-filters-execute-in-angularjs.htm

已经搞定,不要在页面使用 filter,直接在controller使用filter,等filter完成后再赋值给ng-repeat要循环的对象, 总之一句话慎用 filter

新的答案: https://jsfiddle.net/hjzheng/oww0b4ws/7/

fulicat commented 9 years ago

很好

hjzheng commented 9 years ago

@fulicat 其实最好的方式是不要使用filter去实现tree grid, 可以找一下第三方的,看看是如何实现的!例如这个 https://github.com/khan4019/tree-grid-directive