angularjs踩坑系列:指令递归问题
第一次在简书上写文章,写得不好,请多多包含。有不正确的地方请指出来,接受好的意见。
前言
在失业三个多月后,我终于找到了一份前端的工作。接手的是一个重构的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>
写完了之后,经过一番测试,觉得效果还不错:
![](https://img.haomeiwen.com/i12346717/ad6f39d2f08b44ee.png)
心满意足的我就去睡大觉了。
第二天上班,我把头一晚写的代码copy到了项目中去运行,发现不对劲,浏览器一个劲儿的报错,或者就是一直加载中。一开始以为可能时参数写错了吧,毕竟直接copy过来的,于是我就检查了一遍,并将所有参数都认真的查对。当我在按下浏览器刷新按钮之前的一秒,我以为万事大吉,然而。。。
![](https://img.haomeiwen.com/i12346717/c394595bac8de721.png)
调试了半小时,仍然没有结果。忽然想起,我写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