效果图

ang.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
<script src="angular.min.js"></script>
<script src="ang.js"></script>
<link rel="stylesheet" href="css/contest/style.css">
</head>
<body ng-app="myApp" ng-controller="TreeController">

<div class="c-group-r" style="background:#fff;">
    <div class="c-contest-tree-box fix">
        <div class="tree">
            <ul>
                <li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'"></li>
            </ul>
            <div class="loading" ng-show="loadingSwitch">正在加载请稍等</div>
        </div>
        <div class="tree">
            <ul>
                <li ng-show="data.isChecked==1||data.isChecked==2" ng-repeat="data in tree" ng-include="'tree_item_renderer2.html'"></li>
            </ul>
            <div class="loading" ng-show="loadingSwitch">正在加载请稍等</div>
        </div>
    </div>
</div>

</body>
</html>

====================================================================================

<script id="tree_item_renderer.html">

<div>
    <div ng-click="switchOper(data)" ng-class="{'c-contest-menueTri-close':!data.isOpen,'c-contest-menueTri-open':data.isOpen}" ng-show="!data.isLeaf"></div>
    <div class="c-contest-menueTri-none" ng-show="data.isLeaf"><i class="c-contest-menueTri-point" ng-show="data.isChecked=='none'"></i></div>
    <div ng-click="change(data)" ng-class="{'c-contest-checkbox':data.isChecked==0,'c-contest-checkbox-check':data.isChecked==1,'c-contest-checkbox-have':data.isChecked==2}"><span></span></div>
    <span>{{data.name}}</span>
</div>
<ul ng-show="data.isOpen">
    <li ng-repeat="data in data.child" ng-include="'tree_item_renderer.html'"></li>
</ul>

<script>

====================================================================================

<script id="tree_item_renderer2.html">

<div>
    <div ng-click="switchOper(data)" ng-class="{'c-contest-menueTri-close':!data.isOpen,'c-contest-menueTri-open':data.isOpen}" ng-show="!data.isLeaf"></div>
    <div class="c-contest-menueTri-none" ng-show="data.isLeaf"><i class="c-contest-menueTri-point" ng-show="data.isChecked=='none'"></i></div>
    <div ng-click="change(data)" ng-class="{'c-contest-checkbox':data.isChecked==0,'c-contest-checkbox-check':data.isChecked==1,'c-contest-checkbox-have':data.isChecked==2}"><span></span></div>
    <span>{{data.name}}</span>
</div>
<ul ng-show="data.isOpen">
    <li ng-show="data.isChecked==1||data.isChecked==2" ng-repeat="data in data.child" ng-include="'tree_item_renderer2.html'"></li>
</ul>

</script>

=====================================================================================

<script id="ang.js">

  angular.module("myApp", []).
controller("TreeController", ['$scope', function($scope) {
    var gtree = [
        {
            "id": "2",
            "name": "a1",
            "isOpen": true,
            "type": 1,
            "child": [
                {
                    "id": "3",
                    "name": "a2",
                    "isOpen": true,
                    "type": 1,
                    "child": [
                        {
                            "id": "4",
                            "name": "小王",
                            "isChecked": 1,
                            "isOpen": true,
                            "type": 2
                        },
                        {
                            "id": "5",
                            "name": "么么",
                            "isChecked": 0,
                            "isOpen": true,
                            "type": 2
                        },
                        {
                            "id": "6",
                            "name": "你爹",
                            "isChecked": 0,
                            "isOpen": true,
                            "type": 2
                        }
                    ],
                    "child_nums": 3,
                    "isChecked": 2
                }
            ],
            "child_nums": 1,
            "isChecked": 2
        },
        {
            "id": "9",
            "name": "b1",
            "isOpen": true,
            "type": 1,
            "child": [
                {
                    "id": "8",
                    "name": "b2",
                    "isOpen": true,
                    "type": 1,
                    "child": [
                        {
                            "id": "7",
                            "name": "ZXY",
                            "isChecked": 1,
                            "isOpen": true,
                            "type": 2
                        },
                        {
                            "id": "13",
                            "name": "丽丽",
                            "isChecked": 1,
                            "isOpen": true,
                            "type": 2
                        },
                        {
                            "id": "12",
                            "name": "啦啦啦",
                            "isChecked": 1,
                            "isOpen": true,
                            "type": 2
                        }
                    ],
                    "child_nums": 3,
                    "isChecked": 1
                }
            ],
            "child_nums": 1,
            "isChecked": 1
        },
        {
            "id": "14",
            "name": "c1",
            "isOpen": true,
            "type": 1,
            "child": {
                    "isChecked": 0
            },
            "child_nums": 0
        },
        {
            "id": "69473",
            "name": "分组",
            "isOpen": true,
            "type": 1,
            "child": [
                {
                    "id": "15",
                    "name": "分组1",
                    "isOpen": true,
                    "type": 1,
                    "child": [
                        {
                            "id": "23",
                            "name": "测试柯",
                            "isChecked": 0,
                            "isOpen": true,
                            "type": 1,
                            "child": [
                                {
                                    "id": "16",
                                    "name": "测试柯",
                                    "isChecked": 0,
                                    "isOpen": true,
                                    "type": 2
                                }
                            ]
                        },
                        {
                            "id": "24",
                            "name": "美眉",
                            "isChecked": 0,
                            "isOpen": true,
                            "type": 1
                        }
                    ],
                    "child_nums": 2,
                    "isChecked": 0
                },
                {
                    "id": "26",
                    "name": "分组2",
                    "isOpen": true,
                    "type": 1,
                    "child": {
                        "isChecked": 0
                    },
                    "child_nums": 0
                }
            ],
            "child_nums": 2,
            "isChecked": 0
        }
    ];
    tree = [{'name' : "全部", "isRoot":true, "isOpen":true,"type" : 1,"child":gtree,"isChecked":"1","pathes":[]}];
    $scope.tree = tree;
    makeTree($scope.tree,1);
    
    console.log(tree)

//工具函数
    /**
     * 展开关闭
     * @param  {object} data 当前节点数据
     */
    $scope.switchOper = function(data) {
        if(data.isOpen){
            data.isOpen=false;
        }else{
            data.isOpen=true;
        }
    };
    /**
     * 改变选择状态
     * @param  {object} data 当前节点数据
     */
    $scope.change = function(data,type){
        var istotal = 0;
        if(data.isChecked ==0){//非选择状态则全选(遇到有空分组则部分选择)
            if(data.blankChild){
                data.isChecked = 2;
            }else{
                data.isChecked = 1;
            }
            selectAll(data,1);
        }else{//全选状态或者部分全选则取消选择
            data.isChecked = 0;
            selectAll(data,0);
        }
        // console.log(data)
        checkParent(data);
    }
    /**
         * makeTree 加工树数据
         * @param  {object} tree 原始树结构
         * @param  {number} type 获取类型
     */
    function makeTree(tree,type){
        var len = tree.length,
            clen = 0,
            temp = null,
            path = '';
        for(var i=0;i<len;i++){
            if(tree[i].child instanceof Array){
                tree[i].parent ? path=tree[i].parent.path + '["child"]' + '['+i+']' : path='['+i+']';
                tree[i].path = path ;
                temp = tree[i].child;
                clen = temp.length;
                if(clen == 0){
                    tree[i].isLeaf = true;
                    if(tree[i].type == 1){
                        tree[i].isChecked = "none";//无人员分组
                        if(tree[i].parent)
                        tree[i].parent.blankChild = true;//是否含有空分组
                    }
                }
                for(var j=0; j<clen; j++){
                    temp[j].parent = tree[i];
                    // temp[j].path = temp[j].parent.path + 'child';
                    if(temp[j].isChecked==undefined){
                        temp[j].isChecked =0;
                    }
                    if(temp[j].isChecked == 2 && temp[j].parent.isRoot){//当子节点存在中间状态并且其父节点是根节点的时候
                        temp[j].parent.isChecked = 2;
                    }
                }
                makeTree(temp,type);
            }else{
                tree[i].parent ? path=tree[i].parent.path + '["child"]' + '['+i+']' : path='['+i+']';
                tree[i].path = path ;
                if(type == 1){
                    console.log(tree[0].pathes)
                    $scope.tree[0].pathes.push(tree[i].path);
                }else if(type == 2){
                    //如果是多棵树的时候绑定多个scope值用type区分
                }
                tree[i].child = [];
                tree[i].isLeaf = true;
                if(tree[i].type == 1){
                    tree[i].isChecked = "none";//无人员分组
                    if(tree[i].parent)
                    tree[i].parent.blankChild = true;//是否含有空分组
                }
            }
        }
    }
    // 选择父节点
    function checkParent(data){
        if(!data.parent) return;
        var len = data.parent.child.length,
            total = 0,
            have = 0,
            uncheck = 0;
        if(data.isChecked == 2){
            data.parent.isChecked = 2;
        }else{
            for(var i=0;i<len;i++){
                if(data.parent.child[i].isChecked == 1){
                    total++;
                }else if(data.parent.child[i].isChecked == 2){
                    have++;
                }
            }
            if(total == len){
                data.parent.isChecked = 1;
            }else if(total > 0){
                data.parent.isChecked = 2;
            }else if(total == 0){
                if(have>0){
                    data.parent.isChecked = 2;
                }else{
                    data.parent.isChecked = 0;
                }
            }
        }
        checkParent(data.parent);
    }
    /**
    * 选择所有子集
    */
    function selectAll(data, ischeck){
        for(var i=0;i<data.child.length;i++){
            if(data.child[i].isChecked!="none"){
                if(data.child[i].blankChild && ischeck){
                    data.child[i].isChecked = 2;
                }else{
                    data.child[i].isChecked = ischeck;
                }
            }
            if(data.child[i].child.length>0){
                selectAll(data.child[i], ischeck);
            }
        }
        // console.log(data.nodes)
    }
    /**
     * getSelctPersons 遍历所有人员挑出被选则的
     * @param  {string} rootKey    对象的名字
     * @param  {array}  pathes      人员路径数组
     * @return  {array}   persons   被选择的人员数组
     */
    function getSelctPersons(rootKey, pathes){
        var len = pathes.length,
            temp,
            persons = [];
        for(var i=0;i<len;i++){
            temp = eval(rootKey+pathes[i]);
            if(temp.isChecked == 1){
                persons.push({
                    id : temp.id,
                    name : temp.name,
                    department : temp.parent.id
                });
            }
        }
        return persons;
    }
    // getSelctPersons('$scope["tree"]', $scope.tree[0].pathes);//获取所有选择的人员
    /**
     * [removeParent 删除树中的递归访问 parent字段]
     * @param  {object} tree 处理过的树结构数据
     */
    function removeParent(tree){
        var len = tree.length;
        for(var i=0;i<len;i++){
            if(tree[i].parent){
                tree[i].parent = null;
            }
            removeParent(tree[i].child);
        }
    }
}]);

<script>

=======================================css=============================================

@charset "utf-8";
.m-contest-footer {
    padding: 20px 0;
    height:70px;
    text-align: right;
    border-top: 1px solid #e8edf1;
}
.m-contest textarea{resize:none;}
.m-contest em,.m-contest i,.m-contest dfn{font-style:normal;}
.m-contest .z-w60{width:60px!important;}
.m-contest .z-w100{width:100px!important;}
.m-contest .z-inline-block input,.m-contest .z-inline-block select{display:inline-block;}
.c-contest-bar{line-height:30px;color:#666;}
.c-contest-bar .u-radio{padding-top:2px;}
@charset "utf-8";
/* html,body */
html { font-size:1em;-webkit-tap-highlight-color:rgba(0,0,0,0); -webkit-tap-highlight:rgba(0,0,0,0);-webkit-text-size-adjust:none;}
body { font-size:0.75em;}
label { cursor:pointer}
a:link, a:visited { text-decoration:none}
input,button,select,textarea{outline:none} textarea{resize:none;}

a, abbr, acronym, address, applet, article, aside, audio, b, blockquote, big, body, center, canvas, caption, cite, code, command, datalist, dd, del, details, dfn, dl, div, dt, em, embed, fieldset, figcaption, figure, font, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, html, i, iframe, img, ins, kbd, keygen, label, legend, li, meter, nav, menu, object, ol, output, p, pre, progress, q, s, samp, section, small, span, source, strike, strong, sub, sup, table, tbody, tfoot, thead, th, tr, tdvideo, tt,
u, ul, var { margin:0; padding:0}

article, aside, footer, header, hgroup, nav, section, figure, figcaption { display: block}

h1, h2, h3, h4, h5, h6, th, td, table, input, button, select, textarea, sub{ font-size:1em}
body, input, button, select, textarea, sub{ font-family:Arial, sans-serif}
em, cite, address, optgroup { font-style:normal}
kbd, samp, code { font-family:monospace}

img, input, button, select, textarea { vertical-align:middle}
ul, ol { list-style:none}
img, fieldset { border:0}
abbr, acronym { cursor:help; border-bottom:1px dotted black;border:0;font-variant:normal;}
table {    width:100%; border-spacing:0; border:0}
table th, table td { border:0}
legend, hr { overflow:hidden; position:absolute; top:0; left:0}
legend, hr, caption { visibility:hidden; font-size:0; width:0; height:0; line-height:0}
input, select, textarea{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-o-box-sizing:border-box;-ms-box-sizing:border-box;-webkit-appearance:button;-moz-appearance:button;-o-appearance:button;-ms-appearance:button;border-radius:0px;}
sup{vertical-align:text-top;}
sub{vertical-align:text-bottom;}
input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;*font-size:100%;}
:focus{outline:0;}
a{text-decoration:none;outline:none;}
textarea{resize:none;}
i{font-style:initial;}
div, h1, h2, p, table, tr, td{word-wrap:break-word;word-break:break-all;}
.fix{display:inline-block;}
.fix{display:block;}
.fix:after{content:"";display:block;height:0px; clear:both;visibility:hidden;}
div, h1, h2, p, table, tr, td{word-wrap:break-word;word-break:break-all;}
.wbn{word-break:keep-all;white-space:nowrap;}
.wby{word-break:break-all;word-wrap:break-word;white-space:normal;}

input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {color: #999;}
input:-moz-placeholder, textarea:-moz-placeholder {color: #999;}
input::-moz-placeholder, textarea::-moz-placeholder {color: #999;}
input:-ms-input-placeholder, textarea:-ms-input-placeholder {color: #999;}
html,body{min-height:100%;font-family:"microsoft yahei";}
input::-ms-clear, ::-ms-reveal{display:none;}
/*树结构*/
.c-contest-tree-box{width:588px;padding:20px;border:1px solid #eaeaea;border-radius:2px;line-height:30px;font-size:14px;}
.c-contest-tree-box .loading{width:100px;height:100px;padding-top:66px;background:url(../../images/contest/loading-img.png) no-repeat 50% 50%;position:absolute;top:80px;left:70px;}
.c-contest-tree-box .tree div{outline:none;}
.c-contest-tree-box .tree:nth-child(1){margin-right:36px;}
.c-contest-tree-box .tree{float:left;width:254px;height:328px;box-shadow:1px 0 1px rgba(0,0,0,0.1);border:1px solid #d8dde6;border-radius:4px;overflow-y:scroll;position:relative;}
.c-contest-menueTri-close,.c-contest-menueTri-open,.c-contest-menueTri-none{width:20px;height:20px;margin-top:5px;float:left;}
.c-contest-menueTri-close{background:url(../../images/contest/tri-close.png) no-repeat 50% 50%;}
.c-contest-menueTri-open{background:url(../../images/contest/tri-open.png) no-repeat 50% 50%;}
.c-contest-menueTri-point{display:block;width:100%;height:100%;background:url(../../images/contest/tri-point.png) no-repeat 50% 50%;}
.c-contest-menueTri.isleaf{background:none;}
.c-contest-checkbox,.c-contest-checkbox-check,.c-contest-checkbox-have{width:16px;height:16px;border-radius:2px;float:left;margin:7px 5px 0 0;}
.c-contest-checkbox{background:url(../../images/contest/nocheck.jpg) no-repeat 0 0;}
.c-contest-checkbox-check{background:url(../../images/contest/check.jpg) no-repeat 0 0;}
.c-contest-checkbox-have{background:url(../../images/contest/have.jpg) no-repeat 0 0;}
.c-contest-tree-box ul{background:#fff;}
.c-contest-tree-box ul ul{padding-left:12px;}
.c-contest-tree-box ul li > div{margin-bottom:4px;}

angular 嵌套实现树结构 ng-repeat ng-include的更多相关文章

  1. [Angular 6] 初学angular,环境全部最新,[ ng serve ] 不能启动,卡在 95% 不动 => 解决方案

    2018.9.7 问题描述: 通过ng serve命令启动angular应用时,卡在95%, ctrl+c 停掉后看到错误内容为找不到ng_modules下的angular模块下的package.js ...

  2. Part 6 AngularJS ng repeat directive

    ng-repeat is similar to foreach loop in C#. Let us understand this with an example. Here is what we ...

  3. Angular6之ng build | ng build --aot | ng build --prod 差异

    由于写了大半年的项目终于要告一段落并且即将进行第二阶段优化开发,emmm 基础版本已经二十多个模块了,必不可少的优化是很重要的,尽管项目上使用多层嵌套懒加载,但是在首屏加载的时候,任然很慢啊,因为一直 ...

  4. [Angular 2] Using ng-for to repeat template elements

    This lesson covers Angular 2’s version of looping through data in your templates: ng-for. It’s conce ...

  5. angular中关于自定义指令——repeat渲染完成后执行动作

    业务中有时需要在异步获取数据并用ng-repeat遍历渲染完页面后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己动手写.有经验的同学都应该知道,在ng-r ...

  6. Pytorch版本yolov3源码阅读

    目录 Pytorch版本yolov3源码阅读 1. 阅读test.py 1.1 参数解读 1.2 data文件解析 1.3 cfg文件解析 1.4 根据cfg文件创建模块 1.5 YOLOLayer ...

  7. angular 2 - 001 ng cli的安装和使用

    angular cli 创建项目和组件 ng new my-app --skip-install cd my-app cnpm install ng serve localhost:4200 angu ...

  8. Angular CLI 启动 版本ng 4

    npm install -g angular-cli ng -v ng new project_name cd project_name ng serve 浏览器打开输入 localhost:4200

  9. ng之自定义指令

    最近开始研究并使用angular,今天就来简单讲讲对于ng中自定义指令的一下使用心得吧! 相信用过ng的人都对ng中的指令有所了解,指令,我将其理解为AngularJS操作HTML element的一 ...

随机推荐

  1. Spring Controller 获取请求参数的几种方法

    1.直接把表单的参数写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交.若"Content-Type"="application/ ...

  2. POJ C程序设计进阶 编程题#2:角谷猜想

    编程题#2:角谷猜想 来源: POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 所谓角谷 ...

  3. linux下不重启添加硬盘

    linux下热加载磁盘 临时给虚拟机加了一块硬盘,增加后懒得重启,于是看了看热加载 [root@centos5 ~]# cat /proc/scsi/scsiAttached devices:Host ...

  4. Target Operator ID has No Access to Upgrade

    If you are attempting to migrate a project between environments through application designer you mig ...

  5. [leetcode]_String to Integer (atoi)

    非常考虑思维全面性的一道题,考验是否能够考虑本问题的方方面面. 题目:将一个string转换为int.实现函数atoi()的功能. 先应该明确atoi()有哪些特殊功能:(正常的正负数情况我就不列了) ...

  6. DevExpress之ASPxGridView笔记(1)

    1.设置Row(某列)输出格式,例如,在数字前加美元符.每3位以逗号隔开及设置小数点后两位: <dx:GridViewDataTextColumn FieldName="SHOUHUI ...

  7. PHP数组在HTML之中的应用

    <select name="data[status]" id="" <?php if(in_array($list['status'],array( ...

  8. Java实现九九乘法表的输出

    九九乘法表一般为三角形,每个数分别和从1到自身的数相乘然后把结果列出来,即要用到两层循环,外层是从1到9for(i=1;i<=9;i++),内层是当前数和从1到自身相乘for(j=1;j< ...

  9. [转]给C++初学者的50个忠告

    1.把C++当成一门新的语言学习(和C没啥关系!真的.):   2.看<Thinking In C++>,不要看<C++变成死相>:   3.看<The C++ Prog ...

  10. .Net之美

    第1章 C#类型基础 1.1 值类型和引用类型值类型和引用类型是以它们在计算机内存中是如何被分配的来划分的.值类型包括了结构和枚举,引用类型则包括了类. 接口. 委托等. 还有一种特殊的值类型,称为简 ...