Normalizr:如何规范嵌套键并恢复到相同形状?

时间:2018-10-03 23:28:14

标签: javascript redux normalizr

使用代码可能会更清楚。如果我有这样的答复。

{
  id: "1",
  container: {
    sections: [
      {
        id: "a",
        pages: [
          {
            id: "z"
          }
        ]
      }
    ]
  }
}

我真的很想规范其中的sections集合和pages集合。我还需要将其恢复为精确的形状。问题是container没有ID。我尝试的所有事情似乎都无法将其还原。我想我要使用的规范化版本将是类似的。

{
  // the thing that container is in
  project: {  
    id: "1",
    // maybe remove container key, and know I have to normalize
    // and add the key again?
    container: "?"
  },
  sections: {  
    id: "a": {
      pages: ["z"]
    },
  pages: {
    id: "z"
  }
}

任何帮助将不胜感激。同样,这些部分和页面确实是我要规范化和非规范化的内容,而不会丢失顶级密钥中的数据

编辑 稍微改一下这个问题,我发现了类似Normalizr - is it a way to generate IDs for non-ids entity model?的帖子。试图将id添加到没有id的事物中。我并不是真的想要这样,因为我不想仅在下面将container相同或更高级别的内容标准化。

1 个答案:

答案 0 :(得分:0)

您可以将容器包含在项目架构定义中。

const { schema } = require('normalizr');

const pageSchema = new schema.Entity('pages');

const sectionSchema = new schema.Entity('sections', {
    pages: [pageSchema],
});

const projectSchema = new schema.Entity('projects', {
    container: {
        sections: [sectionSchema],
    },
});

在这种情况下,容器将不被标准化。只要它们不具有任何标识属性,就很难将它们视为实体。如果他们这样做,则可以将该属性指定为idAttribute

您最好的选择是在API和normalizr之间的某个级别转换API响应并生成唯一的ID,但这不会给您带来任何正常的好处,如您所链接的问题所指出的那样。

以下是使用上述架构从规范化状态对实体进行规范化的方法:

const { normalize, denormalize } = require('normalizr');

const data = {
  id: "1",
  container: {
    sections: [
      {
        id: "a",
        pages: [
          {
            id: "z"
          }
        ]
      }
    ]
  }
};

const state = normalize(data, projectSchema);
// -> {"entities":{"pages":{"z":{"id":"z"}},"sections":{"a":{"id":"a","pages":["z"]}},"projects":{"1":{"id":"1","container":{"sections":["a"]}}}},"result":"1"}    

denormalize(1, projectSchema, state.entities); 
// -> {"id":"1","container":{"sections":[{"id":"a","pages":[{"id":"z"}]}]}}