使用AngularJS,假设数组$scope.data.children
具有以下结构的项目:
{
"sku" : "<sku>",
"selected" : <boolean>,
"children" : []
}
是否有一种简单的方法可以引用所有selected = true
个孩子,理想情况下会在$scope.data.components
中表示?
所以,例如,如果
[
{"sku" : "A","selected" : true, "children":[
{"sku" : "A1","selected" : true, "children":[]},
{"sku" : "A2","selected" : false, "children":[]}
]},
{"sku" : "B","selected" : false, "children":[
{"sku" : "B1","selected" : false, "children":[]},
{"sku" : "B2","selected" : false, "children":[]}
]},
{"sku" : "C","selected" : true, "children":[
{"sku" : "C1","selected" : true, "children":[]},
{"sku" : "C2","selected" : false, "children":[]}
]},
{"sku" : "D","selected" : false, "children":[
{"sku" : "D1","selected" : false, "children":[]},
{"sku" : "D2","selected" : false, "children":[]}
]}
]
然后
$scope.data.components = [
{"sku" : "A","selected" : true, "children":[
{"sku" : "A1","selected" : true, "children":[]},
},
{"sku" : "C","selected" : true, "children":[
{"sku" : "C1","selected" : true, "children":[]}
}
]
如果$scope.data.children
更新为[{"sku" : "D","selected" : true}]
然后$scope.data.components =
[
{"sku" : "A","selected" : true, "children":[
{"sku" : "A1","selected" : true, "children":[]},
},
{"sku" : "C","selected" : true, "children":[
{"sku" : "C1","selected" : true, "children":[]}
},
{"sku" : "D","selected" : true, "children":[
{"sku" : "D2","selected" : true, "children":[]}
}
]
总结要求:
$scope.data.children
或$scope.data.components
的更改应立即反映在其中。children
selected == true
元素
component
的引用只会显示children
selected == true
。因此,如果"sku":"A"
对node
对象的引用可用,则node.components
将返回node.children
"sku":"A"
个孩子的select == true
。 s res = super(bom_override, self).create(vals)
TypeError: super(type, obj): obj must be an instance or subtype of type
答案 0 :(得分:0)
使用您提供的示例json,我尝试使用forEach in angularjs
我只是通过children array and constructed the component array when needed
angular.forEach($scope.children, function(child) {
var grandChildValue = 0; //value to check for component node already exist
angular.forEach(child.children, function(grandChild) {
if(grandChild.selected) {
if(grandChildValue != 0) {
// if node already exist means it will be added to children from here
angular.forEach($scope.components, function(comp){
if(comp.sku == child.sku) {
comp.children.push(grandChild);
}
});
return;
}
//if node doesn't exist, it will create the node in component array & children inserted
grandChildValue++;
$scope.components.push({
"sku" : child.sku,
"selected": child.selected,
"children":[grandChild]
});
}
});
});
这是一个包含代码的工作人员,
http://embed.plnkr.co/Yv6BaLQQY03TMsnv0yHk/preview
希望这有帮助!
答案 1 :(得分:0)
我们有一个对象数组,每个对象都有一个对象数组,依此类推。这看起来像一个树的数组,该树中的每个节点可以有任意数量的子节点,并且这些子节点中的每一个都可以具有任意数量的子节点,依此类推。因此,问题在于遍历树并仅选择“已选择”的节点。如果我们遇到未选择的节点,我们不会检查它的子节点。
因此我们将遍历数组,并为每个树检查是否选择了根节点,如果是,我们对其子节点执行相同的过程并返回树。
var reduceTreeArray = function (trees) {
return trees.reduce(function (acc, tree) { // walk over the array
tree = getSelectedTree(tree);
if (tree) { // check if we have at least one node
acc.push(tree);
}
return acc; // acc stands for accumulator
}, []);
};
var getSelectedTree = function (node) {
if (node.selected) {
return {
sku: node.sku,
selected: true,
children: reduceTreeArray(node.children) // walk over its children
};
}
return false;
};
var selectedTrees = reduceTreeArray(trees);
这两个相互递归的函数给出了所需的结果,树可以任意深度,但请记住,你可以达到调用堆栈大小。
现在关于实时视图。由于我们可以使用angular,因此如果数据结构已更改并重新计算树,请使用$scope.$watch
方法获取通知。所以:
$scope.$watch('data.children', function (newChildren) {
$scope.data.components = reduceTreeArray(newChildren);
}, true);
请注意,我将true
值作为第二个参数传递。这是因为我们必须进行深入监视,因此即使对象内部的值发生更改(例如,某人更改了对象上的selected
值),我们也会收到通知。
这是一个带有上述内容的plunker。