【问题标题】:Filter tree structure过滤树结构
【发布时间】:2015-06-29 22:54:14
【问题描述】:
我正在尝试迭代一棵树,但不知何故我似乎无法让它按我的意愿工作。
我有一个带有整数的过滤器(由用户选择)
节点看起来像:
- ID:内部
- ParentId:内部
- 孩子:{节点(对象)}
我的树:
树(根)
我想以这样的方式结束。选择的每个节点 + 所选节点的父节点一直到顶部。
树(根)
我目前的解决方案是这样的
organizationIterator = (node, filter, parent, result) ->
_.each(node, (leaf)->
tempLeaf = _.clone(leaf)
tempIndex = filter.indexOf(leaf.organizationId)
if tempIndex > -1
if result[leaf.parentOrganizationId]
tempLeaf.subOrganizations = []
parent.subOrganizations.push tempLeaf
result[parent.organizationId] = parent
else
result[leaf.organizationId] = tempLeaf
else
tempLeaf.notSelected = true
if leaf.subOrganizations
tempLeaf.subOrganizations = []
organizationIterator(leaf.subOrganizations, filter, tempLeaf, result)
)
希望有人可以指导我找到可行的解决方案。
【问题讨论】:
标签:
javascript
filter
tree
coffeescript
underscore.js
【解决方案1】:
我不知道你在 Coffeescript 中是怎么做的,但是在普通的 Javascript 中它看起来像下面这样。希望这可以为您提供一个开始:
//setup
var input = document.getElementById('filter'),
tree = document.getElementById('tree'),
selectedValues = [],
items = tree.getElementsByTagName('li'), afterInsert;
for (var i = 0; i < items.length; i++) {
afterInsert = items[i].firstChild.nextSibling;
items[i].setAttribute('data-id', i);
items[i].insertBefore(document.createTextNode(' ' + (i+1)), afterInsert);
}
input.addEventListener('change', function() {
selectedValues = input.value.split(',');
var count = /[0-9]/g.test(input.value) ? selectedValues.length : items.length;
// if input is non-empty
if (/[0-9]/g.test(input.value)) {
// make the selected values from input of type number and zero-based
while (count--)
selectedValues[count] = parseInt(selectedValues[count]-1);
// THE RECURSIVE FUNCTION
function addParent(node) {
var index = parseInt(node.getAttribute('data-id'));
if (node.nodeName == 'LI') {
// only add an index if it's not already present
if (selectedValues.indexOf(index) === -1)
selectedValues.push(index);
addParent(node.parentNode.parentNode);
}
}
for (var i = selectedValues.length; i--;) {
addParent(items[selectedValues[i]]);
}
// if input is empty, set all items to 'selectedValues'
} else {
while (count--)
selectedValues.push(count);
}
for (var i = items.length; i--;) {
if (selectedValues.indexOf(i) !== -1)
items[i].style.display = 'list-item';
else
items[i].style.display = 'none';
}
}, false);
<p>Write different numbers as comma-separated into the input field</p>Filter: <input type="text" id="filter">
<ul id="tree">
<li>item</li>
<li>item
<ul>
<li>item</li>
<li>item
<ul>
<li>item</li>
</ul>
</li>
<li>item</li>
</ul>
</li>
<li>item
<ul>
<li>item
<ul>
<li>item</li>
<li>item</li>
</ul>
</li>
<li>item</li>
</ul>
</li>
</ul>