angular复选框式js树形菜单(一)
treeView.html
<ul class="tree-view"> <li ng-repeat="item in treeData" ng-include="itemTemplateUrl||'/treeItem.html'" ></li> </ul>
treeItem.html
<i ng-click="itemExpended(item, $event);" class="getItemIcon(item)"></i> <input type="checkbox" ng-model="item.checked" class="check-box" ng-if="canChecked" ng-change="warpCallback('itemCheckedChanged', item, $event)"> <span class='text-field' ng-click="warpCallback('itemClicked', item, $event);">{{item.name}}</span> <ul ng-if="!isLeaf(item)" ng-show="item.$$isExpend"> <li ng-repeat="item in item.childItems" ng-include="itemTemplateUrl||'/treeItem.html'"> </li> </ul>
controller.html
<tree-view tree-data="vm.treeData" itemTemplateUrl="vm.itemTemplateUrl"
item-clicked="vm.itemClicked($item)"
item-checked-changed="vm.itemCheckedChanged($item)" can-checked="true">
</tree-view>
treeView.directive
angular.module('app', []) .directive('treeView',[function(){ return { restrict: 'E', templateUrl: '/treeView.html', scope: { treeData: '=', canChecked: '=', textField: '@', itemClicked: '&', itemCheckedChanged: '&', itemTemplateUrl: '@' }, controller:['$scope', function($scope){ $scope.itemExpended = function(item, $event){ item.$$isExpend = ! item.$$isExpend; $event.stopPropagation(); }; $scope.getItemIcon = function(item){ var isLeaf = $scope.isLeaf(item); if(isLeaf){ return 'fa fa-leaf'; } return item.$$isExpend ? 'fa fa-minus': 'fa fa-plus'; }; $scope.isLeaf = function(item){ return !item.children || !item.children.length; }; $scope.warpCallback = function(callback, item, $event){ ($scope[callback] || angular.noop)({ $item:item, $event:$event }); }; }] }; }]);
treeView.controller
angular.module('app') .controller('treeCtrl',function(){ var vm = this; vm.treeData=[ { id:"0010", fatherId:"0000", name:"流程管理", checked:true, childItems:[ { id:"0020", fatherId:"0010", name:"个人任务池", checked:true, childItems:[ id:"0030", fatherId:"0020", name:"受理", checked:true, childItems:[] ] }, { id:"0021", fatherId:"0010", name:"公共任务池", checked:false, childItems:[] } ] }, { id:"0100", fatherId:"0000", name:"信息查询", checked:true, childItems:[ { id:"0120", fatherId:"0100", name:"计划信息", checked:true, childItems:[] }, { id:"0120", fatherId:"0100", name:"管理人信息", checked:false, childItems:[] } ] } ]; vm.itemCheckedChanged = function (changeItem) { if (hasChildItems(changeItem)) { setChildItems(changeItem); } setParentItems(changeItem); }; function setChildItems(changeItem){ angular.forEach(changeItem.childItems,function(childItem){ changeItem.checked = changeItem.checked; if(hasChildItems(childItem)){ setChildItems(childItem); } }) } function setParentItems(changeItem){ definedParentItem(vm.treeData,changeItem); } function findParentItem(item,changeItem){ definedParentItem(item.childItems,changeItem); } function definedParentItem(childItems,changeItem){ var parentItem = _.find(childItems,{id:changeItem.fatherId}); if(!!parentItem){ parentItem.checked = isAllSelected(parentItem); setParentItems(parentItem); }else{ angular.forEach(childItems,function(childItem){ if(hasChildItems(childItem)){ findParentItem(childItem); } }); } } function isAllSelected(item){ var isSelected = []; if(hasChildItems(item.childItems)){ angular.forEach(item.childItems,function(childItem){ isAllSelected.push(changeItem.checked); }); } return isSelected.indexOf(true)!==-1; } function hasChildItems(item){ return !!item.childItems && item.childItems.length>0; } });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)