1

我有一个实现树结构的对象(例如代表一个项目):

class Project
{
   data: {};
   children: Array<Project>=[];
}

我正在使用来自 Primeng (TreeTable) 的角度组件来可视化这棵树并让用户动态地更改树(添加子项,更改数据值,...)。

这一切都很好。但是当我使用 http.post 将我的对象发送到我的后端时,我得到一个错误(循环值......)。原因是primeng 的组件向我的对象添加了附加属性来管理树(父级、扩展...)。'parent' 属性导致了这个循环值问题。

打字稿中有没有办法将我的对象结构保留在我的应用程序的上下文中?(组件添加的属性对我的代码不可见,因此在使用 http.post 时将被忽略)

在 http.post 函数中,我的对象必须更改为 json 或字符串。是否有可能覆盖避免此错误的方法?(就像 Rails 中的 .as_json 一样)

谢谢,迈克尔

4

2 回答 2

0

通常这是由循环结构引起的......例如,这很好:

class Project
{
   data: {};
   children: Array<Project>=[];
}

const project = new Project();
project.children.push(new Project());

console.log(JSON.stringify(project));

但是如果你要给它自己添加一个对象,或者给它的一个孩子添加一个对象……混乱就会随之而来……

class Project
{
   data: {};
   children: Array<Project>=[];
}

const project = new Project();
project.children.push(new Project());

// No problem
console.log(JSON.stringify(project));

project.children.push(project);

// No end!
console.log(JSON.stringify(project));

这是一个完全有效的内存结构 - 引用绕着圈子转,但最终它是可能的

当你尝试序列化它时,它永远不会结束,因为每次遇到原始项目时,它都会继续循环,没有结束。

解决方案

您需要映射到非循环类型来序列化数据。您可以像这样处理数据丢失:

class Project
{
   data: { example: '4'};
   children: Array<Project>=[];
}

const project = new Project();
project.children.push(new Project());

console.log(JSON.stringify(project));

project.children.push(project);

const getCircularReplacer = () => {
  const seen = new WeakSet;
  return (key, value) => {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return;
      }
      seen.add(value);
    }
    return value;
  };
};

JSON.stringify(project, getCircularReplacer());
于 2018-06-07T15:17:38.990 回答
0

我为我的问题找到了解决方案。我为组件提供了我的树结构的副本,但引用了原始数据哈希。每当我更改树结构(添加节点、删除节点等)时,我都会重新计算一棵干净的树。

工作 - 所以问题解决了。

于 2018-06-08T11:10:53.777 回答