具有不同子名

时间:2016-04-01 09:50:47

标签: javascript angularjs json recursion

我目前正在学习AngularJS,我正在尝试实现一个JSON复杂对象显示器。我在this question甚至here中已经阅读了很多关于此类问题的内容,并且有回应的要素,但在我的情况下,这些并不能帮助我。< / p>

之前提到的主题向我展示了一些好的解决方案,当孩子总是带有相同的名字时(例如,子元素总是被称为#34;孩子&#34;例如1)。但是我们如何处理不同的名字呢?我找了一种方法让孩子们不管它的名字是什么,但是找不到它。

我的JSON对象如下所示:

{
  name: "Something",
  _id: "some ID",
  Firstchildren: [
       {
        name: "Children1"
        type: "Child"
        SecondChildren: [
          {
             name: "ChildrenOfDoom",
             type: "Doom"
             ThirdChildren: [
                {
                 name: "BoredOne",
                 type: "Bored
                },
                {
                 name: "AnotherOne",
                 type: "Boring"
                }
             ]
          },
       <another SecondChildren>
    ]}

基本上我的问题如下:有没有办法以递归方式处理复杂的JSON对象,而不管孩子们的名字是什么?因此,在我们的示例中,最终得到如下显示:

Something
     Child1 : Child
          ChildrenOfDoom : Doom
              BoredOne : Bored
              AnotherOne : Boring
          ChildrenOfChaos : Chaotic
              SomeOne : Random
              ...
          ...
     Child2 : Child
          ...

当然,如果有这样的方式,我想了解它,无论是完整的解决方案,建议,文档还是有用的教程。

提前谢谢!

PS:如果可能,请避免&#34;可能重复&#34;如果他们已经在原始问题中联系起来,我已经完成了。 PPS:尽管有上述第一个,我也不会接受其他相关问题,只要它们在这里没有引用过。

1 个答案:

答案 0 :(得分:1)

此函数返回包含&#34; children&#34;的任何属性的名称。对于给定的对象

var childrenProperty = getChildrenProperty(object);
if (childrenProperty !== null) {
  recursiveFunction(object[childrenProperty]);
}

然后在你的递归函数中,你可以像这样使用它

function getChildrenProperty(object) {
  for (var property in object) {
    if (object.hasOwnProperty(property)) {
      if (property.toLowerCase().indexOf("children") > -1) {
        return property;
      }
      // You also search for cowboys here
      if (property.toLowerCase().indexOf("cowboys") > -1) {
        return property;
      }
      // And for demons, because you need it
      if (property.toLowerCase().indexOf("demons") > -1) {
        return property;
      }
     // As much as you want, you should use a function
     // if you need a lot of cases to check ;)
    }
  }

  return null;
}

[编辑] 如果你想检查多种类型的孩子(例如你在你的结构中介绍兄弟,姐妹或牛仔Beepops),你可以增加你的研究术语:

var app = angular.module("app", []);

app.controller("controller", function($scope) {
  $scope.object = {
    name: "Something",
    _id: "some ID",
    FirstChildren: [{
      name: "Child1",
      type: "Child",
      SecondChildren: [{
        name: "ChildrenOfDoom",
        type: "Doom",
        ThirdChildren: [{
          name: "BoredOne",
          type: "Bored"
        }, {
          name: "AnotherOne",
          type: "Boring"
        }]
      }]
    }, {
      name: "Child2",
      type: "Child",
      SecondChildren: [{
        name: "Child of Child2",
        type: "Space Cowboy"
      }]
    }]
  };

  var str = ""; // The string we'll be creating. We'll add it to scope once everything is done

  // Recursive function, this will keep calling itself if the object has children
  // The `level` parameter is used to determine how many tabs to adds to the start of each line
  function addObjectsToString(objects, level) {
    // We want an array of objects to iterate over and add to the string. So if it isn't an array, make a new array containing only `objects` which is actually a single object
    if (!Array.isArray(objects)) {
      objects = [objects];
    }

    for (var i = 0; i < objects.length; i++) {
      var object = objects[i];

      // Add indentation
      for (var j = 0; j < level; j++) {
        str += "    "; // 4 spaces because tab seemed a bit much
      }

      // Add the object name, presumably all objects will have a name
      str += object.name;

      // If the object has a type add " : type"
      if (angular.isDefined(object.type)) {
        str += " : " + object.type;
      }

      // Add a new line
      str += "\n";

      // If the object has a children property, call this function with reference to the object's children
      var childrenProperty = getChildrenProperty(object);
      if (childrenProperty !== null) {
        addObjectsToString(object[childrenProperty], level + 1);
      }
    }
  }

  // Returns the name of any property containing "children"
  function getChildrenProperty(object) {
    for (var property in object) {
      if (object.hasOwnProperty(property)) {
        if (property.toLowerCase().indexOf("children") > -1) {
          return property;
        }
      }
    }

    return null;
  }

  // Very first call to the recursive function
  addObjectsToString($scope.object, 0);

  // Add the string to the scope so we can display it on the page
  $scope.result = str;
});

还要确保你需要那些&#34;较低的情况&#34;,因为它可能会导致一些问题。我刚遇到一个问题,我的财产就像是#34; halfWay&#34;并且下面提供的这段代码片段无法找到该属性,因为它正在将其转换为&#34;中途&#34;。否则,它的运作非常顺利。

&#13;
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="app" ng-controller="controller">
  <pre>{{result}}</pre>
</div>
&#13;
{{1}}
&#13;
&#13;
&#13;