【问题标题】:Normalizr: how to work with an array of arraysNormalizr:如何使用数组数组
【发布时间】:2018-07-05 23:40:26
【问题描述】:

我正在尝试规范化键盘的配置。这是其中的一小部分:

keyboard.json

{
  "rows": [
    [
      { "label": "~" },
      { "label": "1" },
      { "label": "2" },
      { "label": "3" },
      { "label": "4" }
    ],
    [
      { "label": "tab", size: 1.5 },
      { "label": "Q" },
      { "label": "W" },
      { "label": "E" },
      { "label": "R" }
    ]
  ]
}

我的目标是创建一个标准化对象,如下所示:

{
  entities: {
    keys: {
      'k~0': { label: '~' },
      'k10': { label: '1' },
      // etc..
    },
    rows: {
      0: ['k~0', 'k10'],
      1: ['ktab0', 'kQ0'],
      // etc..
    }
  },
  result: {
    rows: [0, 1, /* etc */]
  }
}

目前我有这个:

import { normalize, schema } from 'normalizr'

const keySchema = new schema.Entity('keys', {}, {
  idAttribute: (k) => {
    return `k${k.label}${k.location || 0}`
  }
})

let rowI = 0

const rowSchema = new schema.Entity('rows', {
  keys: [ keySchema ]
}, {
  // btw: I know this is not the best way to set an id, but I'll solve that later
  idAttribute: (a, b, i) => rowI++
})

const keyboardSchema = {
  rows: [ rowSchema ]
}

export default normalize(keyboardData, keyboardSchema)

这基本上将原始 json 中的行“复制”到实体,而不为每个行实体创建一个新键。见截图:

所以这就是我迷路的地方。我想我需要某种中间步骤,“在”rowSchema 中,但我不明白如何。

任何帮助表示赞赏!

【问题讨论】:

    标签: json reactjs redux normalizr


    【解决方案1】:

    嗯,谢谢 StackOverflow 帮助我 ? 这个问题 :)

    我需要的是 processStrategy 用于 rowSchema 函数。我第一次使用它。花了一些时间,但现在我明白会发生什么了。

    对于任何感兴趣的人,详细分类(自下而上阅读):

    // 5: Lastly here's where we define how a key entity looks like
    const keySchema = new schema.Entity('keys', {}, {
      idAttribute: (k) => {
        // 6: This time we construct the id from properties found in the json
        return `k${k.label}${k.location || 0}`
      }
    })
    
    // 2: Defining an Entity makes it appear in the `entities` object within our normalised data
    const rowSchema = new schema.Entity('rows', {
      // 3: Here we do the same as before. We assign `keys` the keySchema...
      //    ..but wait.. `keys` is not defined in our json. We simply have a nested array. See 4
      keys: [ keySchema ]
    }, {
      // (EXTRA) Each row we assign an id by checking which row's entry matches the current
      idAttribute: (value, parent) => parent.rows.indexOf(value),
      // 4: THIS is how we tell rowSchema that it should assign the current value to keys
      processStrategy: (value) => ({ keys: value })
    })
    
    // 1: This looks like destructuring; `rows` should match rows in the JSON
    //    Here we say that rows contains an array and each entry should be given the "layout" of `rowSchema`
    const keyboardSchema = {
      rows: [ rowSchema ]
    }
    
    
    
    // All nice and ESNexty:
    import { normalize, schema } from 'normalizr'
    
    const keySchema = new schema.Entity('keys', {}, {
      idAttribute: (k) => `k${k.label}${k.location || 0}`
    })
    
    const rowSchema = new schema.Entity('rows', {
      keys: [ keySchema ]
    }, {
      idAttribute: (keys, { rows }) => rows.indexOf(keys),
      processStrategy: (keys) => ({ keys })
    })
    
    const keyboardSchema = {
      rows: [ rowSchema ]
    }
    
    export default normalize(keyboardData, keyboardSchema)

    【讨论】:

    • 这样就可以了,现在行的输出将是0: {keys: ['k~0', 'k10', 'k20']}。想知道我是否可以摆脱那里的 keys 道具。所以它会是:0: ['k~0', 'k10', 'k20']
    猜你喜欢
    • 2018-11-26
    • 2016-06-21
    • 2016-06-20
    • 2018-05-27
    • 2022-01-27
    • 2017-06-21
    • 2018-09-29
    • 2018-05-27
    • 2017-06-05
    相关资源
    最近更新 更多