效果图

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. Azkaban遇到的坑-installation Failed.Error chunking

    在使用azkaban做spark作业调度时,在上传zip包时报installation Failed.Error chunking错误,原来是于我们所编写的应用会上传到 MySQL 存储,过大的zip ...

  2. Yii 操作提示框实现

    如图: html  +  css   代码: 这是 YII  模板的写法 欢迎使用Yii <style> div.success{ background: #C5FBBD; border: ...

  3. web app 开发

    去除手机浏览器标签默认高亮边框 -webkit-tap-highlight-color 属性 属性描述:这个属性可以指设置透明度.如果未设置透明度,iOS上的Safari会给予颜色一个默认的透明度.把 ...

  4. xcode4.5应用程序本地化

    我们在开发一款APP的时候,总是会涉及应用程序国际化的事情,用ios里专业术语叫做本地化,其实都是一个意思,简而言之就是不同的系统语言,显示不同的应用名称.字符串名称.图片名称.等等,除了代码,ios ...

  5. linux积累

    在多文件中批量替换字符串grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

  6. NOJ1142-最大连续和

    最大连续和 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 1282            测试通过 : 230 ...

  7. Java入门到精通——基础篇之static关键字

    一.概述        static 关键字是声明静态变量,静态方法用的.static的含义是属于类且不属于类对象的变量和函数. 二.static的产生.         在创建对象的时候除非用new ...

  8. [目录]Pentaho Kettle解决方案:使用PDI构建开源ETL解决方案

    第一部分:开始 1         ETL入门 1.1   OLTP和数据仓库对比 1.2   ETL是什么 1.2.1          ETL解决方案的演化过程 1.2.2          ET ...

  9. ode.js 版本控制 nvm 和 n 使用 及 nvm 重启终端失效的解决方法

    今天的话题包括2个部分 node.js 下使用 nvm 或者 n 来进行版本控制 nvm 安装node.js 版本后,重启终端 node , npm 环境变量失效 第一部分 用什么来管理 node.j ...

  10. hdu 3172 Virtual Friends

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3172 并查集的运用... #include<algorithm> #include< ...