数据自动提供不同的看法 [英] Provide different views automatically to data

查看:112
本文介绍了数据自动提供不同的看法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用AngularJS,说一个数组 $ scope.data.children 具有以下结构的项目:

  {
 SKU:<&SKU GT;,
 选择:其中,布尔>中
 孩子:[]
}

会不会有一个简单的方法引用的所有选择= TRUE 的孩子,最好再$ P $在psented $ scope.data.components

因此​​,例如,如果

  [
    {SKU:A,选择:真的,孩子:
      {SKU:A1,选择:真的,孩子:[]},
      {SKU:A2,选择:假的,孩子:[]}
    ]},
    {SKU:B,选择:假的,孩子:
      {SKU:B1,选择:假的,孩子:[]},
      {SKU:B2,选择:假的,孩子:[]}
    ]},
    {SKU:C,选择:真的,孩子:
      {SKU:C1,选择:真的,孩子:[]},
      {SKU:C2,选择:假的,孩子:[]}
    ]},
    {SKU:D,选择:假的,孩子:
      {SKU:D1,选择:假的,孩子:[]},
      {SKU:D2,选择:假的,孩子:[]}
    ]}
]

然后

  $ scope.data.components = [
    {SKU:A,选择:真的,孩子:
      {SKU:A1,选择:真的,孩子:[]},
    },
    {SKU:C,选择:真的,孩子:
      {SKU:C1,选择:真的,孩子:[]}
    }
]

如果 $ scope.data.children 更新为 [{SKU:D,选择:真正}]

然后 $ scope.data.components =

  [
    {SKU:A,选择:真的,孩子:
      {SKU:A1,选择:真的,孩子:[]},
    },
    {SKU:C,选择:真的,孩子:
      {SKU:C1,选择:真的,孩子:[]}
    },
    {SKU:D,选择:真的,孩子:
      {SKU:D2,选择:真的,孩子:[]}
    }
]

要总结的要求:


  1. 实时取景 - 对 $ scope.data.children $ scope.data.components 应反映变化两个立即生效。

  2. 不限小孩深度元素应检查选择==真

  3. 一旦虚假检测,没有subchildren应该进行检查。

  4. (可选的,但伟大的,如果可能的话)的任何引用组件将只显示孩子选择==真。所以,如果在SKU的引用:A对象可在节点,那么 node.components 将返回 node.children ,其中SKU:A的儿童选择==真


解决方案

我们有对象的数组,每个对象都有一个对象数组等等。这看起来像树的阵列,在该树中的每个节点可以具有子节点的任意数量,并且每个这些子节点可以有孩子的任意数量等。所以问题是关于遍历一棵树,只选择其中的选择的节点。如果我们遇到这是没有选择的节点,我们没有检查它的孩子。

因此​​,我们将去阵列上方,并为每个树检查如果根节点被选择,如果它是我们做它的子相同的步骤,并返回树

  VAR reduceTreeArray =功能(树){
    返回trees.reduce(功能(ACC,树){//步行阵列上方
        树= getSelectedTree(树);
        如果(树){//检查是否我们至少有一个节点
            acc.push(树);
        }
        返回ACC; // ACC表示累加器
    },[]);
};VAR getSelectedTree =功能(节点){
    如果(node.selected){
        返回{
            SKU:node.sku,
            选择:真的,
            儿童:reduceTreeArray(node.children)//行走在它的孩子
        };
    }
    返回false;
};VAR selectedTrees = reduceTreeArray(树);

这两个相互递归函数给出的期望的结果,树可以是任意的深度,但请记住,你可以到达调用堆栈的大小。

现在对实时取景。既然我们可以利用的角度,让我们使用 $范围。$看,如果数据结构发生了变化,以获得通知方法,并重新计算树。所以:

  $范围。$腕表('data.children',函数(newChildren){
    $ scope.data.components = reduceTreeArray(newChildren);
},真正的);

请注意,我通过了真正值作为第二个参数。这是因为我们要做一个深刻的手表,所以我们得到通知,甚至当一个对象改变里面的值,例如,当有人更改的对象上值。

下面是一个 plunker 与上面的东西。

Using AngularJS, say an array $scope.data.children has item with the following structure:

{
 "sku" : "<sku>",
 "selected" : <boolean>,
 "children" : []
}

Would there be a simple way referencing all selected = true children, ideally represented in $scope.data.components?

So, for example, if

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

then

$scope.data.components = [
    {"sku" : "A","selected" : true, "children":[
      {"sku" : "A1","selected" : true, "children":[]},
    },
    {"sku" : "C","selected" : true, "children":[
      {"sku" : "C1","selected" : true, "children":[]}
    }
]

if $scope.data.children is updated to [{"sku" : "D","selected" : true}]

then $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":[]}
    }
]

To summarise the requirements:

  1. Live view - changes against $scope.data.children or $scope.data.components should be reflected on both immediately.
  2. Any depth of children elements should be checked for selected == true
  3. Once a false is detected, no subchildren should be checked.
  4. (optional but great if possible) Any reference to component will only display children with selected == true. So, if a reference to the "sku":"A" object is available at node, then node.components will return node.children where "sku":"A"'s children's select == true

解决方案

We have an array of objects, each of these objects has an array of objects and so on. This looks like an array of trees, each node in that tree can have an arbitrary number of child nodes, and each of these child nodes can have an arbitrary number of children and so on. So the problem is about traversing a tree and selecting only the nodes which are "selected". If we encounter a node which is not selected, we do not check it's children.

So we will go over the array, and for each tree check if the root node is selected and if it is we do the same procedure on its children and return the tree.

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);

These two mutually recursive functions gives as the desired result, the tree can be arbitrarily deep, although keep in mind that you can reach the call stack size.

Now about the live view. Since we can use angular, let's use the $scope.$watch method to get notified if the data structure has changed and recalculate the trees. So:

$scope.$watch('data.children', function (newChildren) {
    $scope.data.components = reduceTreeArray(newChildren);
}, true);

Notice that I passed the true value as second argument. This is because we have to do a deep watch, so we get notified even when the value inside an object changes, for example when someone changes selected value on an object.

Here's a plunker with the above stuff.

这篇关于数据自动提供不同的看法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆