8

如何使用normalizr来处理通过标准关键的嵌套标准化JSON API响应{ data: ... }

例如一个Book

{
    data: {
        title: 'Lord of the Rings',
        pages: 9250,
        publisher: {
            data:  {
                name: 'HarperCollins LLC',
                address: 'Big building next to the river',
                city: 'Amsterdam'
            },
        },
        author: {
            data: {
                name: 'J.R.R Tolkien',
                country: 'UK',
                age: 124,
            }
        }
    }
}   

我将如何设计模式来处理嵌套数据键?

4

2 回答 2

6

对于响应中的每个实体,您应该创建它自己的架构。在您的示例中,

我们有三个实体 -books和:authorspublishers

// schemas.js
import { Schema } from 'normalizr';

const bookSchema = new Schema('book');
const publisherSchema = new Schema('publisher');
const authorSchema = new Schema('author');

如果某个实体包含需要规范化的嵌套数据,我们需要使用define它的模式方法。该方法接受具有嵌套规则的对象。

如果我们需要对实体进行规范化publisherauthor道具化book,我们应该传递一个对象以define与我们的响应具有相同的结构:

// schemas.js
bookSchema.define({
  data: {
    publisher: publisherSchema,
    author: authorSchema
  }
});

现在我们可以标准化我们的响应:

import { normalize } from 'normalizr';
import { bookSchema } from './schemas.js';

const response = {
    data: {
        title: 'Lord of the Rings',
        pages: 9250,
        publisher: {
            data:  {
                name: 'HarperCollins LLC',
                address: 'Big building next to the river',
                city: 'Amsterdam'
            },
        },
        author: {
            data: {
                name: 'J.R.R Tolkien',
                country: 'UK',
                age: 124,
            }
        }
    }
}

const data = normalize(response, bookSchema);
于 2016-07-01T14:24:18.640 回答
3

我相信你所追求的是使用assignEntity可以在选项中传递的函数normalize。在这种情况下,它允许我们在适当的时候过滤掉多余的data属性并直接进入下面的值。

有效地assignEntity让您控制每个数据键的标准化方式。在这里查看更多关于它是如何工作的信息。

我把它放在一起作为演示,看看:http ://requirebin.com/?gist=b7d89679202a202d72c7eee24f5408b6 。这是一个片段:

book.define({
  data: {
    publisher: publisher,
    author: author,
    characters: normalizr.arrayOf(character)
  }}
);

publisher.define({
  data: {
    country: country
  }
});

const result = normalizr.normalize(response, book, { assignEntity: function (output, key, value, input) {
  if (key === 'data') {
    Object.keys(value).forEach(function(d){
      output[d] = value[d];
    })
  } else {
    output[key] = value;
  }
}});

还请特别参见 Ln 29,其中的数组characters有一些对象,其中包含嵌套的信息,而另data一些则没有。一切都正确归一化。

我还添加了一些部分来展示它如何处理数组和深度嵌套的数据,请country参阅publisher.

使用提供的数据,由于缺少 id,您将需要一个 slug,每个模式也包含在示例中。

Normalizr 太棒了,我希望这有助于解释更多关于它的信息:)

于 2016-07-04T16:58:34.537 回答