看 ng深度剖析 上有個遞歸樹,模仿寫了下,
用到的知識有:指令裏的compile,link,服務
代碼如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="bootstrap.css">
<script src="angular.js"></script>
</head>
<body ng-app="App" ng-controller="MyApp">
<ul>
<li bf-template="item" ng-repeat="node in $dataSource">
<span><input type="checkbox" ng-change="change(node)" ng-model="node.IsChecked">{{node.id}}</span>
<ul>
<li recurse="node.Child"></li>
</ul>
</li>
</ul>
<script>
var app = angular.module('App', []);
app.controller('MyApp', function($scope, data) {
$scope.item = data;
});
app.directive('bfTemplate', function(data, SetChildChecked, pp) {
return {
restrict: 'AE',
priority: 2000,
compile: function(ele, attr) {
var template = ele[0].outerHTML;
return function(scope, element, attrs) {
scope.$template = template;
if (!scope.$dataSource) {
scope.$dataSource = scope.$eval(attrs.bfTemplate);
}
scope.change = function(i) {
SetChildChecked(i);
pp(i, data);
};
}
}
}
});
app.directive('recurse', function($compile) {
return {
restrict: 'AE',
link: function(scope, element, attrs) {
var subScope = scope.$new(true);
subScope.$dataSource = scope.$eval(attrs.recurse);
var dom = $compile(scope.$template)(subScope);
element.replaceWith(dom);
}
}
});
app.factory('data', function() {
var a = [{
id: 'a1',
Child: [{
id: 'a2',
Child: [{
id: 'a3',
Child: [{
id: 'a5'
}, {
id: 'ads'
}]
}]
}, {
id: 'c2',
Child: [{
id: 'c3',
Child: [{
id: 'c5'
}, {
id: 'cds'
}]
}, {
id: 'd3',
Child: [{
id: 'd5'
}, {
id: 'dds'
}]
}]
}]
}, {
id: 'b1',
Child: [{
id: 'b2',
Child: [{
id: 'b3',
Child: [{
id: 'b5'
}, {
id: 'bds'
}]
}]
}]
}];
return a;
});
app.factory('SetChildChecked', function() {
return SetChildChecked;
//根據父節點狀態設置子節點的狀態
function SetChildChecked(m) {
if (m.IsChecked) {
if (m.Child != null) {
for (var i = 0; i < m.Child.length; i++) {
m.Child[i].IsChecked = true;
m.IsChecked = true;
if (m.Child[i].Child != null) {
SetChildChecked(m.Child[i])
}
}
}
} else {
if (m.Child != null) {
for (var i = 0; i < m.Child.length; i++) {
m.Child[i].IsChecked = false;
if (m.Child[i].Child != null) {
SetChildChecked(m.Child[i])
}
}
}
}
}
});
app.factory('pp', function() {
return pp;
//根據子節點狀態設置父節點的狀態
function pp(tar, data1) {
var SetParentChecked = function(tar, data) {
for (var j = 0; j < data.length; j++) {
for (var i = 0; i < data[j].Child.length; i++) {
if (data[j].Child[i].id == tar.id) {
var n = 0;
for (var k = 0; k < data[j].Child.length; k++) {
if (data[j].Child[k].IsChecked) {
n++;
}
}
if (n) {
data[j].IsChecked = true;
} else {
data[j].IsChecked = false;
}
SetParentChecked(data[j], data1);
} else {
if (data[j].Child[i].Child) {
SetParentChecked(tar, data[j].Child);
}
}
}
}
};
SetParentChecked(tar, data1);
}
})
</script>
</body>
</html>