最近做了个销售区域限制的功能,具体需求是这样的:展示地区信息,共有三级,分别是省、市、区,如下图:
由于之前的需求只有两级地区的交互并且比较简单,在加入了三级地区并提出了一堆要求后描述起来比较麻烦所以直接贴出代码,本文主要目的是给自己写个备忘录如果将来有类似的需求可以直接修改使用,因为需求不断的更改导致匆匆写出来这个逻辑,等有空闲时间也会自己优化一下并更新本文,代码中也写了一些关键注释,有朋友能看得懂我这个小菜鸟写的逻辑并且有更好的方案的话非常欢迎交流学习哈,代码放出:
显示端:
<div class="modal-body" >
<label><input type="checkbox" ng-click="selectAll($event)" ng-checked="isSelectAll()" > 全选</label>
<label ng-show="selectedParentArea.length!=0||selectedChildAreas.length!=0||selectedChildChildAreas.length!=0"><input type="checkbox" ng-click="converse($event)" ng-checked="" > 反选</label>
<ul class="nav" >
<li ng-repeat="areaParent in areaParentList"><i class={{state[$index]}} ng-click="areaChange($index)"></i>
{{areaParent.name}}<input type="checkbox" ng-click="selectParentArea($index,$event,areaParent)" ng-checked="isSelectedParent(areaParent.id)">
<ul ng-show="state[$index]=='fa fa-fw fa-angle-down'">
<li class="child" ng-repeat="areaChild in areaChildList[$index]"><i class={{childState[$parent.$index][$index]}} ng-click="areaChildChange($parent.$index,$index)"></i>
{{areaChild.name}}<input type="checkbox" ng-click="selectAreaChild($parent.$index,$event,areaChild,areaParent)" ng-checked="isSelectedChild($parent.$index,areaChild.id,areaParent.id)" >
<ul ng-show="childState[$parent.$index][$index]=='fa fa-fw fa-angle-down'">
<li class="childChild" ng-repeat="areaChildChild in areaChildChildList[$parent.$index][$index]">
{{areaChildChild.name}}<input type="checkbox" ng-click="selectAreaChildChild($event,$parent.$parent.$index,$parent.$index,$index,areaParent,areaChild,areaChildChild)" ng-checked="isSelectedChildChild(areaChild.id,areaParent.id,areaChildChild.id)" >
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
控制端:
$http({//0级地区查询
method:"GET",
url:$constens.API.URL_AREAPARENT_LIST,
}).success(function(data,status,headers,config){
$scope.areaParentList = data;
$scope.areaParentList.splice(0, 1);
//将0级添加>图标状态
for(var i=0;i<$scope.areaParentList.length;i++){
$scope.state.push("fa fa-fw fa-angle-right");
}
//获取所有0级地区下面的1级地区
if($scope.areaParentList!== undefined && $scope.areaParentList.length != 0 ){
var idArray = new Array();
for(var i=0;i<$scope.areaParentList.length;i++){
var parentId = $scope.areaParentList[i].id;
var data={
id:parentId
}
idArray.push(data);
}
$http({
method : "GET",
url:$constens.API.URL_GET_ALL_CHILDAREA,
params : { jsonParentIds : JSON.stringify(idArray) }
}).success(function(data, status, headers, config) {
$scope.areaChildList=data;
for (var k = 0; k < $scope.selectedChildAreas.length; k++) {
for (var i = 0; i < $scope.areaChildList.length; i++) {
for (var j = 0; j < $scope.areaChildList[i].length; j++) {
if($scope.selectedChildAreas[k].id==$scope.areaChildList[i][j].id){
$scope.state[i]="fa fa-fw fa-angle-down";
}
}
}
}
//将1级地区添加>图标状态
var array=new Array();
$scope.childState= new Array();
for(var i=0;i<$scope.areaChildList.length;i++){
for (var j = 0; j < $scope.areaChildList[i].length; j++) {
array.push("fa fa-fw fa-angle-right");
}
$scope.childState.push(array);
}
$http({// 获取2级地区
method : "POST",
url:$constens.API.URL_GET_ALL_AREA
}).success(function(data, status, headers,config) {
$scope.areaChildChildList=data;
for (var i = 0; i < $scope.selectedChildChildAreas.length; i++) {
for (var j = 0; j < $scope.areaChildChildList.length; j++) {
for (var k = 0; k < $scope.areaChildChildList[j].length; k++) {
for (var p = 0; p < $scope.areaChildChildList[j][k].length; p++) {
if($scope.selectedChildChildAreas[i].id==$scope.areaChildChildList[j][k][p].id){
$scope.state[j]="fa fa-fw fa-angle-down";
$scope.childState[j][k]="fa fa-fw fa-angle-down";
}
}
}
}
}
});
});
}
});
//点击0级改变树级结构
$scope.areaChange = function(index){
if($scope.state[index]=="fa fa-fw fa-angle-right"){
$scope.state[index]="fa fa-fw fa-angle-down";
}else {
$scope.state[index]="fa fa-fw fa-angle-right";
}
}
//点击1级改变树级结构
$scope.areaChildChange = function(parentIndex,index){
if($scope.childState[parentIndex][index]=="fa fa-fw fa-angle-right"){
$scope.childState[parentIndex][index]="fa fa-fw fa-angle-down";
}else {
$scope.childState[parentIndex][index]="fa fa-fw fa-angle-right";
}
}
//判断已选择的id是否在地区对象数组中的方法
function idIsExist(array,id){
var tempArray = new Array();
for(var i = 0; i < array.length; i++){
tempArray.push(array[i].id);
}
return tempArray.indexOf(id);
}
//全选操作
$scope.selectAll = function($event){
var checkbox = $event.target;
if(checkbox.checked){
$scope.selectedParentArea=angular.copy($scope.areaParentList);
$scope.selectedChildAreas.length=0;
$scope.selectedChildChildAreas.length=0;
}else {
$scope.selectedParentArea.length=0;
}
}
//反选操作,此处思路是将获取的三级地区的数组备份,然后将选择的地区从备份数组中删去,然后根据逻辑处理备份数组并将里面的id保存
$scope.converse = function($event){
var checkbox = $event.target;
if(checkbox.checked){
var childPath=new Array();
var parentPath=new Array();
var tempParentAreaList = angular.copy($scope.areaParentList);
var tempChildAreaList = angular.copy($scope.areaChildList);
var tempChildChildAreaList = angular.copy($scope.areaChildChildList);
for (var i = 0;i < $scope.selectedChildChildAreas.length; i++) {
for (var j = 0; j < tempChildChildAreaList.length; j++) {
for (var k = 0; k < tempChildChildAreaList[j].length; k++) {
for (var p = 0; p < tempChildChildAreaList[j][k].length; p++) {
if($scope.selectedChildChildAreas[i].id==tempChildChildAreaList[j][k][p].id){
tempChildChildAreaList[j][k].splice(p,1);
}
}
}
}
}
//处理反选的2级地区
$scope.selectedChildChildAreas.length=0;
for (var i = 0; i < tempChildChildAreaList.length; i++) {
for (var j = 0; j < tempChildChildAreaList[i].length; j++) {
if(tempChildChildAreaList[i][j].length!=$scope.areaChildChildList[i][j].length){
parentPath[i]=true;
$scope.selectedChildChildAreas=$scope.selectedChildChildAreas.concat(tempChildChildAreaList[i][j]);
childPath.push(i+","+j);
}
}
}
//将2级区域所属的1级区域从数组除删去
console.log(JSON.stringify(childPath));
for (var i = childPath.length-1; i >=0 ; i--) {
var path = childPath[i].split(",");
tempChildAreaList[path[0]].splice(path[1],1);
}
for (var i = 0; i < $scope.selectedChildAreas.length; i++) {
for (var j = 0; j < tempChildAreaList.length; j++) {
for (var k = 0; k < tempChildAreaList[j].length; k++) {
if($scope.selectedChildAreas[i].id==tempChildAreaList[j][k].id){
parentPath[j]=true;
tempChildAreaList[j].splice(k,1);
}
}
}
}
//处理反选的1级地区
$scope.selectedChildAreas.length=0;
for (var i = 0; i < tempChildAreaList.length; i++) {
if(tempChildAreaList[i].length!=$scope.areaChildList[i].length){
parentPath[i]=true;
$scope.selectedChildAreas=$scope.selectedChildAreas.concat(tempChildAreaList[i]);
}
}
//将1,2级区域所属的0级区域从数组除删去
for (var i = parentPath.length-1; i >=0; i--) {
if(parentPath[i]==true){
tempParentAreaList.splice(i,1);
}
}
for (var i = 0; i < $scope.selectedParentArea.length; i++) {
for (var j = 0; j < tempParentAreaList.length; j++) {
if($scope.selectedParentArea[i].id==tempParentAreaList[j].id){
tempParentAreaList.splice(j,1);
}
}
}
//处理反选的0级地区
$scope.selectedParentArea.length=0;
if(tempParentAreaList.length!=$scope.areaParentList.length){
$scope.selectedParentArea=$scope.selectedParentArea.concat(tempParentAreaList);
}
}else {
$scope.selectedParentArea.length=0;
$scope.selectedChildAreas.length=0;
$scope.selectedChildChildAreas.length=0;
}
}
//0级地区全选操作
$scope.selectParentArea = function (index,$event,data) {
var checkbox = $event.target;
if (checkbox.checked){//选中0级地区
if(idIsExist($scope.selectedParentArea,data.id)==-1){
$scope.selectedParentArea.push(data);
}
}else {
var index=idIsExist($scope.selectedParentArea,data.id);
$scope.selectedParentArea.splice(index, 1);
}
var indexArray = new Array();
//点击或取消0级地区时删除其所有的1级地区
for (var i = 0; i < $scope.selectedChildAreas.length; i++) {
if(data.id==$scope.selectedChildAreas[i].parentId){
indexArray.push(i);
}
}
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildAreas.splice(indexArray[i], 1);
}
//点击或取消0级地区时删除其所有的2级地区
for (var i = 0; i < $scope.selectedChildChildAreas.length; i++) {
var areaIds=$scope.selectedChildChildAreas[i].path.split(",");
if(data.id==areaIds[0]){
$scope.selectedChildChildAreas.splice(i, 1);
}
}
};
//更新1级地区的选择
$scope.selectAreaChild = function (parentIndex,$event,areaChild,parentArea) {
var checkbox = $event.target;
if(idIsExist($scope.selectedParentArea,parentArea.id) >= 0){//全选情况下更新1级地区
if (!checkbox.checked){
var index=idIsExist($scope.selectedParentArea,parentArea.id);
$scope.selectedParentArea.splice(index, 1);
//将除点击的1级地区以外的所有该父地区下的1级地区存入数组
for(var i=0;i<$scope.areaChildList[parentIndex].length;i++){
if(areaChild.id!=$scope.areaChildList[parentIndex][i].id){
$scope.selectedChildAreas.push($scope.areaChildList[parentIndex][i]);
}
}
//删除该1级地区下的所有2级地区
var indexArray=new Array();
for (var i = 0; i < $scope.selectedChildChildAreas.length; i++) {
if($scope.selectedChildChildAreas[i].parentId==areaChild.id){
indexArray.push(i);
}
}
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildChildAreas.splice(indexArray[i], 1);
}
}
}else {
if (checkbox.checked){
if(idIsExist($scope.selectedChildAreas,areaChild.id)==-1){
$scope.selectedChildAreas.push(areaChild);
//删除该1级地区下的所有2级地区
var indexArray=new Array();
for (var i = 0; i < $scope.selectedChildChildAreas.length; i++) {
if($scope.selectedChildChildAreas[i].parentId==areaChild.id){
indexArray.push(i);
}
}
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildChildAreas.splice(indexArray[i], 1);
}
}
//单选时把子地区全选后添加父地区id到数组并删除子地区全部id
var indexArray = new Array();
var childDeleteArray = new Array();
for (var i = 0; i < $scope.selectedChildAreas.length; i++) {
if(parentArea.id==$scope.selectedChildAreas[i].parentId){
indexArray.push(i);
childDeleteArray.push($scope.selectedChildAreas[i]);
}
}
//全部选中
if($scope.areaChildList[parentIndex].length==indexArray.length){
//添加0级地区
if(idIsExist($scope.selectedParentArea,parentArea.id)==-1){
$scope.selectedParentArea.push(parentArea);
}
//删除1级地区
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildAreas.splice(indexArray[i], 1);
}
//删除已选择的2级地区
indexArray.length=0;
for (var i = 0; i < $scope.selectedChildChildAreas.length; i++) {
for (var j = 0; j < childDeleteArray.length; j++) {
if($scope.selectedChildChildAreas[i].parentId==childDeleteArray[j].id){
indexArray.push(i);
}
}
}
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildChildAreas.splice(indexArray[i], 1);
}
}
}else {
$scope.selectedChildAreas.splice(idIsExist($scope.selectedChildAreas,areaChild.id), 1);
//取消选择1级地区时,删除其所有2级子地区
var indexArray = new Array();
for (var i = 0; i < $scope.selectedChildChildAreas.length; i++) {
if(areaChild.id== $scope.selectedChildChildAreas[i].parentId){
indexArray.push(i);
}
}
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildChildAreas.splice(indexArray[i], 1);
}
}
}
};
//选择2级地区操作
$scope.selectAreaChildChild = function($event,parentIndex,childIndex,areaParent,areaChild,areaChildChild){
var checkbox = $event.target;
if(checkbox.checked){//选中2级地区
if(idIsExist($scope.selectedChildChildAreas,areaChildChild.id)==-1){
$scope.selectedChildChildAreas.push(areaChildChild);
}
//单选时把2级地区全选后添加1级地区id到数组并删除子地区全部id
var indexArray = new Array();
for (var i = 0; i < $scope.selectedChildChildAreas.length; i++) {
if(areaChild.id==$scope.selectedChildChildAreas[i].parentId){
indexArray.push(i);
}
}
//2级地区全部选中
if($scope.areaChildChildList[parentIndex][childIndex].length==indexArray.length){
//添加1级地区
if(idIsExist($scope.selectedChildAreas,areaChild.id)==-1){
$scope.selectedChildAreas.push(areaChild);
}
//删除2级地区
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildChildAreas.splice(indexArray[i], 1);
}
//当单选时所有1级地区全选后添加0级地区id到数组并删除子地区全部id
indexArray = new Array();
var childDeleteArray = new Array();
for (var i = 0; i < $scope.selectedChildAreas.length; i++) {
if(areaParent.id==$scope.selectedChildAreas[i].parentId){
indexArray.push(i);
childDeleteArray.push($scope.selectedChildAreas[i]);
}
}
//1级地区全部选中
if($scope.areaChildList[parentIndex].length==indexArray.length){
//添加0级地区
if(idIsExist($scope.selectedParentArea,areaParent.id)==-1){
$scope.selectedParentArea.push(areaParent);
}
//删除1级地区
for (var i = indexArray.length-1; i >= 0; i--) {
$scope.selectedChildAreas.splice(indexArray[i], 1);
}
}
}
}else {//取消选择
if(idIsExist($scope.selectedParentArea,areaParent.id) >= 0){//已选择0级地区情况下取消选择2级地区则删除0级地区
var index=idIsExist($scope.selectedParentArea,areaParent.id);
$scope.selectedParentArea.splice(index, 1);
//将除点击的1级地区以外的所有该父地区下的1级地区存入数组
for(var i=0;i<$scope.areaChildList[parentIndex].length;i++){
if(areaChild.id!=$scope.areaChildList[parentIndex][i].id){
$scope.selectedChildAreas.push($scope.areaChildList[parentIndex][i]);
}
}
//将除点击的2级地区以外的所有该父1级地区下的2级地区存入数组
for(var i=0;i<$scope.areaChildChildList[parentIndex][childIndex].length;i++){
if(areaChildChild.id!=$scope.areaChildChildList[parentIndex][childIndex][i].id){
$scope.selectedChildChildAreas.push($scope.areaChildChildList[parentIndex][childIndex][i]);
}
}
}else if(idIsExist($scope.selectedChildAreas,areaChild.id) >= 0){//选择了1级地区的情况下取消选择2级地区,删除1级地区
//删除该1级地区
var index = idIsExist($scope.selectedChildAreas,areaChild.id);
$scope.selectedChildAreas.splice(index, 1);
//将除点击的2级地区以外的所有该父1级地区下的2级地区存入数组
for(var i=0;i<$scope.areaChildChildList[parentIndex][childIndex].length;i++){
if(areaChildChild.id!=$scope.areaChildChildList[parentIndex][childIndex][i].id){
$scope.selectedChildChildAreas.push($scope.areaChildChildList[parentIndex][childIndex][i]);
}
}
}else{
var index = idIsExist($scope.selectedChildChildAreas,areaChildChild.id);
$scope.selectedChildChildAreas.splice(index, 1);
}
}
};
//检查2级地区是否被选中
$scope.isSelectedChildChild = function (childId,parentId,areaChildChildId) {
if(idIsExist($scope.selectedParentArea,parentId) >= 0){
return true;
}
if(idIsExist($scope.selectedChildAreas,childId) >= 0){
return true;
}
return idIsExist($scope.selectedChildChildAreas,areaChildChildId) >=0;
};
//检查1级地区是否被选中
$scope.isSelectedChild = function (childId,parentId) {
if(idIsExist($scope.selectedParentArea,parentId) >= 0){//选择了对应的上一级地区
return true;
}
return idIsExist($scope.selectedChildAreas,childId) >=0;
};
//检查0级地区是否被选中
$scope.isSelectedParent = function (parentId) {
return idIsExist($scope.selectedParentArea,parentId) >= 0;
};
//检查全选按钮是否启用
$scope.isSelectAll = function(){
return $scope.selectedParentArea.length==$scope.areaParentList.length;
}