自动为数据

时间:2015-05-20 14:18:04

标签: javascript angularjs data-binding

使用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":[]}
    }
]

总结要求:

  1. 实时视图 - 针对$scope.data.children$scope.data.components的更改应立即反映在其中。
  2. 应检查children
  3. 的任何深度的selected == true元素
  4. 一旦检测到错误,就不应检查子项。
  5. (可选但很好,如果可能)任何对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

2 个答案:

答案 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