4

我很难在本地化的博客应用程序中构建我的数据。

我的应用程序以三种语言(英语、法语和俄语)显示带有嵌入图片(一对多)的帖子。

访问者可以选择其语言环境。编辑可以用三种语言编辑其帖子的本地化版本。

目前,我的商店的结构如下所示:

{ articles:
  {
    en: {
      1: { id: 1, title: "my first title", body: "my first body", picture_ids: [1, 2, 3]},
      2: { id: 2, title: "my second title", body: "my second body", picture_ids: [1, 4, 5]},
      3: { id: 3, title: "my third title", body: "my third body", picture_ids: [6, 7, 8]},
      ...
    },
    fr: {
      1: { id: 1, title: "mon premier titre", body: "mon premier corps de texte", picture_ids: [1, 2, 3]},
      2: { id: 2, title: "mon second titre", body: "mon second corps de texte", picture_ids: [1, 4, 5]},
      3: { id: 3, title: "mon troisième titre", body: "mon troisième corps de texte", picture_ids: [6, 7, 8]},
      ...
    }
  },
  pictures:
   {
      en: {
        1: { id: 1, title: "My great picture", url: "http://..."},
        2: { id: 2, title: "My other great picture", url: "http://..."},
        3: { id: 3, title: "My not so great picture", url: "http://..."},
        ...
      },
      fr: {
        1: { id: 1, title: "Ma superbe photo", url: "http://..."},
        2: { id: 2, title: "Mon autre superbe photo", url: "http://..."},
        3: { id: 3, title: "Ma photo pas vraiment superbe", url: "http://..."},
        ...
      }
   },
   editStateOfFieldsOfArticles:
   {
      en: {
        1: { title: true, body: false },
        2: { title: false, body: true },
        3: { title: false, body: false },
        ...
      },
      fr: {
        1: { title: false, body: false },
        2: { title: false, body: false },
        3: { title: true, body: true },
        ...
      }
   }
}

在这个阶段,我的 reducer 并不算太臃肿,但我觉得我应该进一步规范化,以便预测何时添加与文章相关的标签、作者和其他国际化项目。

所以我正在考虑(i)在商店中为语言创建一个额外的字典,(ii)“扁平化”所有其他字典以摆脱“语言环境”子存储键,(iii)在每个中添加一个 language_id 字段存储在其他字典中的项目和 (iv) 将我的每个字典中的数字键修改为复合键。这看起来像这样:

{languages:
  {
    1: {id: 1, locale: "en", long: "English"},
    2: {id: 2, locale: "fr", long: "Français"},
    3: {id: 3, locale: "ru", long: "русская"}
  }
  articles:
  {
    11: {id: 1, title: "my first title", body: "my first body", picture_ids: [1, 2, 3], language_id: 1},
    21: {id: 2, title: "my second title", body: "my second body", picture_ids: [1, 4, 5], language_id: 1},
    31: {id: 3, title: "my third title", body: "my third body", picture_ids: [6, 7, 8], language_id: 1},
    42: {id: 1, title: "mon premier titre", body: "mon premier corps de texte", picture_ids: [1, 2, 3], language_id: 2},
    52: {id: 2, title: "mon second titre", body: "mon second corps de texte", picture_ids: [1, 4, 5], language_id: 2},
    62: {id: 3, title: "mon troisième titre", body: "mon troisième corps de texte", picture_ids: [6, 7, 8], language_id: 2},
    ...
  },
  pictures:
  {
    11: {id: 1, title: "My great picture", url: "http://...", language_id: 1},
    21: {id: 2, title: "My other great picture", url: "http://...", language_id: 1},
    31: {id: 3, title: "My not so great picture", url: "http://...", language_id: 1},
    12: {id: 1, title: "Ma superbe photo", url: "http://...", language_id: 2},
    22: {id: 2, title: "Mon autre superbe photo", url: "http://...", language_id: 2},
    32: {id: 3, title: "Ma photo pas vraiment superbe", url: "http://...", language_id: 2},
    ...
  },
  editStateOfFieldsOfArticles:
  }
    11: {title: true, body: false, language_id: 1},
    21: {title: false, body: true, language_id: 1},
    31: {title: false, body: false, language_id: 1},
    12: {title: false, body: false, language_id: 2},
    22: {title: false, body: false, language_id: 2},
    32: {title: true, body: true, language_id: 2},
    ...
  }
}

“articles”、“pictures”和“editStatesOfFieldsOfArticles”字典的键的最后一位将对应于 locale/language_id,而其他数字将对应于项目 id。

我发现当我有适用于所有三种语言的商店修改时,我会从这种更扁平的结构中受益,因为我不需要迭代语言(例如,如果我删除一篇文章,该文章应该全部删除)三种语言,我目前必须在本地化子词典和所有辅助商店的子词典(例如“editStateOfFieldsOfArticles”(我还有一些其他这样的辅助词典))上做一个 for...in。

但是,我不完全确定我是否真的会从进一步展平我的哈希中获得任何其他好处(并且 for...in 循环不会有问题,只需管理三种语言 - 此外,在我的用例中,我需要删除一篇文章,并且这种删除需要反映在所有三种语言中,我仍然需要遍历三种语言数组以删除扁平文章字典中的三个相应记录)。

另外,我担心性能问题:因为我会将我的整个集合(文章或任何其他国际化项目)存储在同一个平面树下,无论它们涉及什么语言,我担心访问这些值可能会减慢比较到一个更结构化的树,我可以通过“子键”向下访问本地化分支来访问项目——事实上,后端数据库将本地化的文章存储在不同的本地化表中)。

我将非常感谢任何有为国际化内容或其他具有复杂交叉关系的商店构建 Redux 商店的经验的人,他们可以就自己的经验提供一些反馈或建议或提示: - 代码可读性,特别是在减速器和记忆的选择器, - 比较嵌套树与扁平树的性能, - 进一步规范化与保持“一点”嵌套的整体优势。

4

1 回答 1

0

这个派对迟到了,但如果你仍然好奇的话。

我认为你的第一个实现绝对是优越的。超过 3 个项目的 for 循环不是一项繁重的交易,您可以(并且应该)将其分解为辅助函数:

var forEachLanguage = function(state, dataType, callback){
    var languages_data = state[dataType];
    for(language_index in languages_data){
        var data = languages_data[language_index];
        callback(data);
    }
}

//Example for deleting item 2 from articles
forEachLanguage(state, 'articles', function(data){
    delete data[2];
});

此外,如果您担心重复查找会变得不必要地昂贵(尽管实际上,我认为这不是问题),您可以使用Reselect来缓存您的查找并制作包含语言环境的可重用查找函数。

于 2016-09-18T04:19:34.910 回答