程序员从入门到放弃

angularjs踩坑系列:指令递归问题

2018-05-30  本文已影响147人  曦惜夕

第一次在简书上写文章,写得不好,请多多包含。有不正确的地方请指出来,接受好的意见。

前言

在失业三个多月后,我终于找到了一份前端的工作。接手的是一个重构的angularjs项目,ng版本为1.4.9。于是,我的踩坑之路开始了。

正文

在项目中有一个模块,是关于附件管理的,功能类似于云盘。其中一个需求是:上传文件时要在目录树上选择一个目录。由于本人懒得去找插件,本着造轮子的精神,回家(注意,不是在公司)自己动手去实现了一下。其代码也不难,也就是用递归将目录一层一层的取出来罢了。代码如下:

angular.module('directive.tree', [])
    .directive('dyTree', [function () {
        return {
            restrict: 'E',
            replace: true,
            scope: true,
            bindToController: {
                treeData: '=',
                ngModel: '='
            },
            controllerAs: '$ctrl',
            templateUrl: 'directive/tree/tree.html',
            controller: function ($scope) {
                var $ctrl = this
                // 添加选中效果,并为ngModel赋值
                $ctrl.onSelect = function(item) {
                    __recursion($ctrl.treeData);
                    $ctrl.ngModel = item
                    item.itemActive = true
                }
                // 递归取消选中效果
                function __recursion(list) {
                    if (list && list.length) {
                        for (var i in list) {
                            list[i].itemActive = false
                            __recursion(list[i].children)
                        }
                    }
                }
                // 当指令外部清空ngModel的值时,取消选中效果
                $scope.$watch('$ctrl.ngModel', function(newVal) {
                    if (!newVal) {
                        __recursion($ctrl.treeData)
                    }
                })
            }
        };
    }])
    .directive('dyTreeItem', [function () {
        return {
            restrict: 'E',
            replace: true,
            scope: true,
            bindToController: {
                treeList: '=',
                onSelect: '&'
            },
            controllerAs: '$ctrl',
            templateUrl: 'directive/tree/treeItem.html',
            controller: function () {
                var $ctrl = this
                $ctrl.getItem = function (item) {
                    $ctrl.onSelect({item: item})
                }
                $ctrl.onChildrenSelect = function (item) {
                    $ctrl.onSelect({item: item})
                }
            }
        }
    }])



其中tree.html模板内容如下:

<div class="dy-tree">
    <dy-tree-item tree-list="$ctrl.treeData" on-select="$ctrl.onSelect(item)"></dy-tree-item>
</div>



treeItem.html

<ul>
    <li ng-repeat="item in $ctrl.treeList" class="list-item" ng-init="item.isShowChildren = false">
        <a class="df df-down" ng-click="item.isShowChildren = !item.isShowChildren" ng-show="item.children.length > 0"
           ng-class="{active:item.isShowChildren}"></a>
        <div>
            <a href="javascript:void(0)" ng-click="$ctrl.getItem(item)" ng-class="{active: item.itemActive}">
                <i class="df df-folder"></i>
                <span ng-bind="item.name"></span>
            </a>
        </div>
        <dy-tree-item ng-show="item.isShowChildren" tree-list="item.children"
                      on-select="$ctrl.onChildrenSelect(item)"></dy-tree-item>
    </li>
</ul>



写完了之后,经过一番测试,觉得效果还不错:

效果如图所示

心满意足的我就去睡大觉了。

第二天上班,我把头一晚写的代码copy到了项目中去运行,发现不对劲,浏览器一个劲儿的报错,或者就是一直加载中。一开始以为可能时参数写错了吧,毕竟直接copy过来的,于是我就检查了一遍,并将所有参数都认真的查对。当我在按下浏览器刷新按钮之前的一秒,我以为万事大吉,然而。。。

堆栈溢出

调试了半小时,仍然没有结果。忽然想起,我写demo的时候,是在家写的,angularjs版本为1.6.6,而公司项目中使用的angularjs版本为1.4.9。死马当做活马医吧,我决定升级一下项目中的版本。

受到项目中其他库的影响,不能升至1.6.6,于是将版本升级至1.5.0。再次打开浏览器,一切都正常了。

总结

angularjs在1.5以前,不支持指令的递归,这一点务必小心。

最后,把代码分享给大家,里面包含一些别的有用的指令:

github地址:https://github.com/RilyZhang/angularjs-directive-dy

预览地址:https://rilyzhang.github.io/angularjs-directive-dy/

欢迎Issues,欢迎star

上一篇 下一篇

猜你喜欢

热点阅读