我一直在做一些擺弄(哈哈),我想出了一個解決方案,似乎很通用......意思是,你可以擁有儘可能多的嵌套複選框,因爲你的心臟需要。我相信我會遵循一些奇怪的做法,並且可能會有一些領域的表現可能會增加 - 這絕對是通過很多對象循環 - 所以隨時批評它!我很樂意聽到任何反饋。
該代碼可在此找到jsFiddle。我也會在這裏發佈。
的HTML
<!DOCTYPE html>
<html>
<head>
<script src="../js/angularjs106.js"></script>
<script src="angular_checkbox.js"></script>
<link rel="stylesheet" href="angular_checkbox.css" />
</head>
<body ng-app>
<div ng-controller="Ctrl">
<ul>
<li>
<input type="checkbox" value="allChecks.id" ng-model="allChecks.isChecked" ng-change="checkChange(allChecks)">
<label>{{allChecks.id}}</label>
</li>
<li ng-repeat="child in allChecks.children">
<input type="checkbox" ng-model="child.isChecked" ng-change="checkChange(child)">
<label>{{child.id}}</label>
<ul>
<li ng-repeat="grandchild in child.children">
<input type="checkbox" ng-model="grandchild.isChecked" ng-change="checkChange(grandchild)">
<label>{{grandchild.id}}</label>
<ul>
<li ng-repeat="grandgrandchild in grandchild.children">
<input type="checkbox" ng-model="grandgrandchild.isChecked" ng-change="checkChange(grandgrandchild)">
<label>{{grandgrandchild.id}}</label>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
JavaScript的
function Ctrl($scope) {
function Node(id, isChecked, parent) {
this.id = id;
this.isChecked = isChecked;
this.parent = parent;
this.children = [];
}
var parent = new Node('ALL', true, "");
var child1 = new Node('Child 1', true, parent);
var gchild1 = new Node('Grandchild 1', true, child1);
var gchild2 = new Node('Grandchild 2', true, child1);
var gchild3 = new Node('Grandchild 3', true, child1);
child1.children.push(gchild1, gchild2, gchild3);
var child2 = new Node('Child 2', true, parent);
var child3 = new Node('Child 3', true, parent);
var child4 = new Node('Child 4', true, parent);
var gchild4 = new Node('Grandchild 4', true, child4);
var gchild5 = new Node('Grandchild 5', true, child4);
var gchild6 = new Node('Grandchild 6', true, child4);
var ggchild1 = new Node('Grandgrandchild 1', true, gchild6);
var ggchild2 = new Node('Grandgrandchild 2', true, gchild6);
var ggchild3 = new Node('Grandgrandchild 3', true, gchild6);
gchild6.children.push(ggchild1, ggchild2, ggchild3);
child4.children.push(gchild4, gchild5, gchild6);
var child5 = new Node('Child 5', true, parent);
parent.children.push(child1, child2, child3, child4, child5);
$scope.allChecks = parent;
function parentCheckChange(item) {
for (var i in item.children) {
item.children[i].isChecked = item.isChecked;
if (item.children[i].children) {
parentCheckChange(item.children[i]);
}
}
}
function childCheckChange(parent) {
var allChecks = true;
for (var i in parent.children) {
if (!parent.children[i].isChecked) {
allChecks = false;
break;
}
}
if (allChecks) {
parent.isChecked = true;
}
else {
parent.isChecked = false;
}
if (parent.parent) {
childCheckChange(parent.parent);
}
}
$scope.checkChange = function(item) {
// We're handling the ALL checkbox
if (item.id === $scope.allChecks.id) {
parentCheckChange(item);
}
// We're handling the toggling of all of the children here
else {
if (item.children) {
parentCheckChange(item);
}
childCheckChange(item.parent);
}
};
}
微小的CSS
ul {
list-style: none;
}
無論如何,我想編輯找出找到對象中父項的方法。事實證明,原生JavaScript對象不包含對子對象的引用,所以我決定創建一個名爲Node的類。當我實例化節點時,我可以將父項設置爲包含子項的對象。一旦我這樣做,遞歸變得相當容易。
parentCheckChange在我們意識到我們有父級時調用。 childCheckChange在孩子的支票變化(duh!)時被調用,但它被用來監視父母的所有孩子......如果它們都被選中,那麼我們需要確保父項已被選中,並且由於這個父項已被選中,我們需要檢查是否應該檢查它的父項(遞歸)。
代碼可能有點混亂,所以如果您感到困惑,請提問。
我最近寫了這樣的東西:http://jsfiddle.net/langdonx/hQqQV/2/。我只是使用模型,並通過一些數組迭代,看看是否一切都檢查(而不是檢查DOM元素)。請參閱'$ scope.groupChecked'和'_syncGroupCheckBox'(由'$ scope.unitChecked'調用)。 – Langdon 2013-04-23 17:29:52
這可能會對JavaScript部分有所幫助,但在決定變得更加花哨之前,我對更簡單的方法更感興趣。儘管欣賞代碼! – incutonez 2013-04-24 00:54:42
不幸的是沒有更簡單的方法。這不能簡單地通過HTML來完成。見米斯科的評論在這裏:https://github.com/angular/angular.js/pull/1057 – Langdon 2013-04-24 13:47:26