现在在我的记录中:
14.3,14.2和14.1属于Id = 30的部分。
我正在努力实现以下目标:
1)默认情况下,会选择前2个ID。如果用户尝试选择属于第30部分的id = 71,则不应允许用户选择id = 71,因为更高版本的第30部分已被选中,即id = 76。
2)现在,如果用户取消选中id = 77(33),则应允许用户检查id = 71,因为现在没有选择不同的部分,因此用户应该允许检查所有部分id = 30但是一旦用户选择了不同的部分,则应该取消选中下部。
我的代码问题:
1)当我取消选中16.1并尝试检查14.2时,我不允许检查它。我应该允许检查14.2,因为现在这里没有不同的部分。
2)默认情况下会检查16.1和14.3。现在当我检查15.1然后再检查14.1然后14.3取消选中这是错误的,因为14.3在部分id = 30中最高,所以我不能检查14.1。
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.myArray = [
{
"id": 77,
"selected": true,
"part": 33,
"name": "16.1",
},
{
"id": 76,
"part": 30,
"selected": true,
"name": "14.3",
},
{
"id": 71,
"part": 30,
"selected": false,
"name": "14.2",
},
{
"id": 70,
"part": 31,
"selected": false,
"name": "15.1",
},
{
"id": 69,
"part": 30,
"selected": false,
"name": "14.1",
},
{
"id": 68,
"part": 29,
"selected": false,
"name": "13.1",
},
{
"id": 55,
"part": 26,
"selected": false,
"name": "12.1",
}
,
{
"id": 54,
"part": 25,
"selected": false,
"name": "11.2",
}
,
{
"id": 53,
"part": 25,
"selected": false,
"name": "11.1",
}
];
$scope.checkItem = function (item) {
if (item.selected) {
var index = $scope.myArray.map(m=>m.id).indexOf(item.id);
var previousPart = {};
for (var i = index - 1; i >= 0; i--) {
if ($scope.myArray[i].selected) {
previousPart = $scope.myArray[i];
break;
}
}
if (item.part != previousPart.part) {
for (var i = 0; i < $scope.myArray.length; i++) {
if (($scope.myArray[i].part == item.part && $scope.myArray[i].part != item.part)
&& $scope.myArray[i].selected) {
$scope.myArray[i].selected = false;
break;
}
}
}
else
item.selected = false;
}
};
});
&#13;
<!DOCTYPE html>
<html ng-app="myApp" ng-controller="myCtrl">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<div ng-repeat="item in myArray">
<input ng-model="item.selected" ng-click="checkItem(item)" type="checkbox" />{{ item.name }}
</div>
</body>
</html>
&#13;
答案 0 :(得分:3)
我会采取不同的方法。将一些逻辑分离到服务中可以帮助我保持代码更清晰。它将更易于维护,调试和测试。 fiddle
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, myCollection) {
$scope.myArray = myCollection.items;
// Call function every time an item was checked
$scope.checkItem = function(item) {
// Remap collection items before and after
myCollection.mapCheckedItems();
// Do something with the user's interaction only if there are
// different selected parts by definition
if (item.selected && myCollection.selectedPartsOnly.length > 1) {
// Iterate through the selected parts
myCollection.selectedPartsOnly.map(part => {
// Get the array of items belonging to the exact part number
var map = myCollection.selectedPartsMap[part];
for (var j = map.length - 1; j > 0; j--) {
// By definition deselect all but the highest version.
// Happens if different part numbers selected simultaneously
map[j].selected = false;
}
})
}
// Recalculate collection map to keep it up to date with the
// items' array
myCollection.mapCheckedItems();
};
});
app.service('myCollection', function() {
// Init the collection object
var self = {};
// Function to calculate and map items' dependencies
self.mapCheckedItems = mapCheckedItems;
// This holds a list of the selected unique part numbers
// Used to determine needed action easier. By definition if only
// one part number is selected and used to iterate through the map
self.selectedPartsOnly = [];
// This is the important dictionary where the part numbers is mapped
// to its child items. Easy access to items grouped by a part number
self.selectedPartsMap = {};
// The actual array definition
self.items = [{
"id": 77,
"selected": true,
"part": 33,
"name": "16.1",
}, {
"id": 76,
"part": 30,
"selected": true,
"name": "14.3",
}, {
"id": 71,
"part": 30,
"selected": false,
"name": "14.2",
}, {
"id": 70,
"part": 31,
"selected": false,
"name": "15.1",
}, {
"id": 69,
"part": 30,
"selected": false,
"name": "14.1",
}, {
"id": 68,
"part": 29,
"selected": false,
"name": "13.1",
}, {
"id": 55,
"part": 26,
"selected": false,
"name": "12.1",
}, {
"id": 54,
"part": 25,
"selected": false,
"name": "11.2",
}, {
"id": 53,
"part": 25,
"selected": false,
"name": "11.1",
}];
// Init the helpers once on start. This will be executed only once
mapCheckedItems();
// Return the service object to be accessed from the controller
return self;
// This function will create and update the objects mapping
function mapCheckedItems() {
// Reset the helpers
self.selectedPartsOnly = [];
self.selectedPartsMap = {};
// Now we iterate through the selected items.
self.items
.filter(item => item.selected)
.map(item => {
// Map every selected item directly to one part number
mapSelectedParts(item);
// Determine what part numbers are in use.
mapSelectedPartsOnly(item.part);
})
}
function mapSelectedPartsOnly(part) {
if (self.selectedPartsOnly.indexOf(part) == -1)
self.selectedPartsOnly.push(part);
}
function mapSelectedParts(item) {
if (!self.selectedPartsMap[item.part])
self.selectedPartsMap[item.part] = [];
self.selectedPartsMap[item.part].push(item);
}
})
&#13;
<!DOCTYPE html>
<html ng-app="myApp" ng-controller="myCtrl">
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<div ng-repeat="item in myArray">
<input ng-model="item.selected" ng-click="checkItem(item)" type="checkbox" />{{ item.name }}
</div>
</body>
</html>
&#13;
答案 1 :(得分:1)
我已经创建了一个解决方案,可以实现您的两个要点,并解决您上面提到的问题。
您需要仅在控制器中更新checkItem
功能
$scope.checkItem = function(item) {
if (item.selected) {
var otherExists = $scope.myArray.filter(function(m) {
return ((m.part != item.part) && m.selected);
}).length;
var selfExists = $scope.myArray.filter(function(m) {
return ((m.part == item.part) && m.selected);
}).length - 1;
if (!!otherExists) {
if (!!selfExists) {
var selectedIsLower = $scope.myArray.filter(function(m) {
return ((m.part == item.part) && (m.id > item.id) && m.selected);
}).length;
if (!!selectedIsLower) {
item.selected = false;
} else {
$scope.myArray.filter(function(m) {
return (m.part == item.part);
}).forEach(function(m) {
m.selected = false;
});
item.selected = true;
}
} else {
item.selected = false;
var allSelectedIds = [];
var allSelected = $scope.myArray.filter(function(m) {
return m.selected;
});
allSelected.map(m => m.part).forEach(function(a) {
if (allSelectedIds.indexOf(a) < 0) { //skip duplicate id
allSelectedIds.push(a);
}
});;
if (allSelectedIds.length == 1) {
var maxEle = {};
allSelected.forEach(function(m, count) {
if (maxEle.id) {
(maxEle.id > m.id) && (m.selected = false);
}
maxEle.id = m.id;
maxEle.count = count;
});
}
item.selected = true;
}
}
}
};
工作fiddle