Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 从JSON响应生成角度组件所需的新格式_Angular_Typescript - Fatal编程技术网

Angular 从JSON响应生成角度组件所需的新格式

Angular 从JSON响应生成角度组件所需的新格式,angular,typescript,Angular,Typescript,我从API端点返回了以下JSON: [ { "id": 1, "title": "Smells like", "object": "", "children": [ { "id": 2, "title": "Liqui

我从API端点返回了以下JSON:

[
    {
      "id": 1,
      "title": "Smells like",
      "object": "",
      "children": [
        {
          "id": 2,
          "title": "Liquid",
          "object": {
            "objectid": 1,
            "title": "My object also have children",
            "children": []
          },
          "children": [
            {
              "id": 3,
              "title": "Loyal",
              "object": "",
              "children": []
            },
            {
              "id": 4,
              "title": "Smart",
              "object": "",
              "children": [
                {
                  "id": 5,
                  "title": "Smart",
                  "object": "",
                  "children": []
                }
              ]
            }
          ]
        },
        {
          "id": 6,
          "title": "Just empty",
          "object": {
            "objectid": 2,
            "title": "Title of my object",
            "children": []
          },
          "children": []
        }
      ]
    },
    {
      "id": 10,
      "title": "Apple",
      "object": "",
      "children": [
        {
          "id": 11,
          "title": "Ink",
          "object": "",
          "children": []
        },
        {
          "id": 12,
          "title": "Whatever",
          "object": "",
          "children": []
        }
      ]
    }
  ]
您可以将其复制粘贴到此处:然后单击树查看器以查看其作为树的外观

我需要将json转换为我使用的角度组件所期望的格式,如下所示:

[
  new Link({
    id: 1,
    label: "Smells like",
    title: "Smells like",
    object: "",
    children: [
      new Link({
        id: 2,
        label: "Liquid",
        title: "Liquid",
        object: {
          objectid: 1,
          title: "My object also have children",
          children: [],
        },
        children: [
          new Link({
            id: 3,
            label: "Loyal",
            title: "Loyal",
            object: "",
            children: [],
          }),
          new Link({
            id: 4,
            label: "Smart",
            title: "Smart",
            object: "",
            children: [
              new Link({
                id: 5,
                label: "test",
                title: "test",
                object: "",
                children: [],
              }),
            ],
          }),
        ],
      }),
      new Link({
        id: 6,
        label: "Just empty",
        title: "Just empty",
        object: { objectid: 2, title: "Title of my object", children: [] },
        children: [],
      }),
    ],
  }),
  new Link({
    id: 10,
    label: "Apple",
    title: "Apple",
    object: "",
    children: [
      new Link({ id: 11, title: "Ink", object: "", children: [] }),
      new Link({
        id: 12,
        label: "Whatever",
        title: "Whatever",
        object: "",
        children: [],
      }),
    ],
  }),
];
如你所见

它使用新链接包装根节点和子节点 它添加了一个标签,可以是标题的副本 同一json中可能还有其他对象也有子属性,比如示例中的那些对象,不需要包装器新链接。 你知道我如何用typeScript从第一个结构创建第二个结构吗?
我指的是如何迭代并找到所有根节点和子节点,并在需要时创建包含新链接包装的新变量。

创建节点时可以使用简单的递归。 下面是一个函数,它应该有帮助:

const createLink = (itemList) => itemList.map(item => {
    new Link({
        id: item.id,
        label: item.label,
        title: item.title,
        object: item.object,
        children: item.children.length ? createLink(item.children) : []
    })
})
此函数将遍历响应中的所有项,当它有子项时,它将只调用自身并遍历所有子项。 另外,在遍历子级之前,您应该检查它是否有这些子级,如果没有,只需添加空数组,正如我看到的,您需要这些子级

--编辑--

我看到对象中也有子数组。我建议您创建助手函数,该函数将使用createLink函数为子对象重新创建对象:

const createLink = (itemList) => itemList.map(item => {
    new Link({
        id: item.id,
        label: item.label,
        title: item.title,
        object: createObject(item.object),
        children: createLink(item.children)
    })
})

const createObject = (object) => {
    return {
        objectid: object.objectid,
        title: object.title,
        children: createLink(object.children)
    }
}
--编辑--

我认为需要更多的解释

因此,使用createLink函数,您将映射从订阅中获得的所有项目。例如,您希望在订阅中调用createLink函数,并将其分配给变量,因为它返回一个新数组:

this.someService().subscribe(response => {
  this.convertedTree = this.createLink(response));
}
首先,您要做的是创建链接类,以便可以创建它的新实例:

export class Link {
  id: string;
  label: string;
  title: string;
  object: any;
  children: any[];

  constructor(id, title, object, children) {
    this.id = id;
    this.label = title;
    this.title = title;
    this.object = object;
    this.children = children;
  }
}
我更新了函数,使其能够正常工作,还添加了一些检查数组或对象是否为空:

createLink(itemList: any): any {
    if (!itemList.length) {
      return [];
    }

    return itemList.map(item => (
      new Link(
        item.id,
        item.title,
        this.createObject(item.object),
        this.createLink(item.children)
      )));
  }

  createObject(object: any): any {
    if (!Object.keys(object).length) {
      return {};
    }

    return {
      objectid: object.objectid,
      title: object.title,
      children: this.createLink(object.children)
    }
  }
现在createLink函数将遍历nodeTree的响应,并为每个项创建一个新的链接实例,如果它有子项,它将在子项数组中创建新的链接实例,并且它将深入到至少子项上的链接实例

节点内的对象将使用createObject函数创建,它将只返回空对象或带有objectId、标题和子对象的对象

我已经更新/创建了stackblitz,包括我刚才写的所有内容:

对不起,我不知道该怎么办?我订阅了该服务,我得到了一个带有对象和数组的JSON响应。我如何使用你的代码在根节点和子节点之前有一个带有“新链接”包装的变量?eZkkimo你能在这里检查并解释如何转换JSON,包括帖子中描述的“新链接”吗?@WilliamBird我已经更新了我的答案,同时查看stackblitz,因为它可以帮助您直观地看到所有内容。非常感谢您的帮助!谢谢!