我正在尝试在递归树中为我的节点添加唯一标题。
因此,当我为节点提供标题时,它应该检查该标题是否已被其他节点使用。如果采用它,它应该警告用户,它应该将该节点值重置为先前的值。
没有两个节点应该具有相同的标题。
但是这里结构是递归的,所以我不知道如何做到这一点。
注意:我想在文本框失去焦点时立即执行此操作。
var app = angular.module("myApp", []);
app.controller("TreeController", function ($scope) {
$scope.delete = function (data) {
data.nodes = [];
};
$scope.add = function (data) {
var post = data.nodes.length + 1;
var newName = data.name + '-' + post;
data.nodes.push({ name: newName, nodes: [],selected : false, myObj: { name: newName} });
};
$scope.tree = [{ name: "Node", nodes: [], selected: false }];
$scope.setActive = function ($event, data) {
$event.stopPropagation();
$scope.selectedData = data;
clearDivSelection($scope.tree);
data.selected = true;
};
function clearDivSelection(items) {
items.forEach(function (item) {
item.selected = false;
if (item.nodes) {
clearDivSelection(item.nodes);
}
});
}
$scope.checkDuplicateNodeName = function () {
alert()
}
});
ul {
list-style: circle;
}
li {
margin-left: 20px;
}
.active { background-color: #ccffcc;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="myApp" ng-controller="TreeController">
<li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'"></li>
<script type="text/ng-template" id="tree_item_renderer.html">
<div ng-class="{'active': data.selected}" > {{data.myObj.name}}</div>
<button ng-click="add(data)">Add node</button>
<button ng-click="delete(data)" ng-show="data.nodes.length > 0">Delete nodes</button>
<ul>
<li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'" ng-click="setActive($event, data)"></li>
</ul>
</script>
<div style="margin-left:100px;">
Title : <input type="text" ng-model="selectedData.myObj.name" ng-blur="checkDuplicateNodeName()" />
Location : <input type="text" ng-model="selectedData.myObj.location" />
</div>
</ul>
答案 0 :(得分:3)
您可以使用类似于clearDivSelection
方法的递归方法:
function isDuplicated (node, title) {
var result = false;
if (node.nodes && node.nodes.length > 0) result = node.nodes.reduce(function (result, node) {
return isDuplicated(node, title);
}, false);
return result && node.name === title;
}
或(以记忆为代价),您可以维护标题列表:
$scope.titles = {};
$scope.add = function (data) {
var post = data.nodes.length + 1;
var newName = data.name + '-' + post;
if ($scope.titles[newName]) return; // refuse to add
$scope.titles[newName] = true;
data.nodes.push({
name: newName,
nodes: [],
selected : false,
myObj: {
name: newName
}
});
};
我不确定你的意思
应该将该节点值重置为之前的值。
如果你“添加”新对象,你将没有“以前的价值” - 但我会把这一点留给你。无论如何,这应该让你开始。
答案 1 :(得分:3)
true
。如果有欺骗行为,请使用最后一个有效名称,否则更新最后一个有效名称。如果您只想在节点树中搜索dupes,则需要存储对父节点的引用,并使用getTree
方法确定要搜索的根节点。 / p>
var app = angular.module("myApp", []);
app.controller("TreeController", function($scope) {
$scope.delete = deleteNodes;
$scope.add = add;
$scope.setActive = setActive;
$scope.checkDuplicateNodeName = checkDuplicateNodeName;
$scope.trees = [{
name: "Node",
nodes: [],
selected: false
},{
name: "Node2",
nodes: [],
selected: false
}];
function deleteNodes(data) {
data.nodes = [];
}
function add(data) {
var post = data.nodes.length + 1;
var newName = data.name + '-' + post;
data.nodes.push({
name: newName,
nodes: [],
selected: false,
validatedName: newName
});
}
function setActive($event, data) {
$event.stopPropagation();
if($scope.selectedData) {
$scope.selectedData.selected = false;
}
$scope.selectedData = data;
data.selected = true;
}
function checkDuplicateNodeName() {
if(!$scope.selectedData)
return;
var dupe = false;
for(var idx = 0; idx < $scope.trees.length; idx++) {
if(isDuplicateName($scope.trees[idx], $scope.selectedData)) {
dupe = true;
break;
}
}
if(dupe){
alert('The name "' + $scope.selectedData.name + '" already exists');
$scope.selectedData.name = $scope.selectedData.validatedName;
} else {
$scope.selectedData.validatedName = $scope.selectedData.name;
}
}
function getTree(node){
while(node.parent) {
node = node.parent;
}
return node;
}
function isDuplicateName(node, nodeToCheck) {
var dupeName = node != nodeToCheck && node.name && nodeToCheck.name && node.name == nodeToCheck.name;
if(dupeName) return true;
if(node.nodes){
for(var idx=0; idx< node.nodes.length; idx++) {
if(isDuplicateName(node.nodes[idx], nodeToCheck)){
return true;
}
}
}
return false;
}
});
&#13;
ul {
list-style: circle;
}
li {
margin-left: 20px;
}
.active {
background-color: #ccffcc;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="myApp" ng-controller="TreeController">
<li ng-repeat="data in trees" ng-include="'tree_item_renderer.html'"></li>
<script type="text/ng-template" id="tree_item_renderer.html">
<div ng-class="{'active': data.selected}"> {{data.name}}</div>
<button ng-click="add(data)">Add node</button>
<button ng-click="delete(data)" ng-show="data.nodes.length > 0">Delete nodes</button>
<ul>
<li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'" ng-click="setActive($event, data)"></li>
</ul>
</script>
<div style="margin-left:100px;">
Title : <input type="text" ng-model="selectedData.name" ng-blur="checkDuplicateNodeName()" /> Location : <input type="text" ng-model="selectedData.myObj.location" />
</div>
</ul>
&#13;