构建本地化反应/冗余应用程序的存储
Structuring the store of a localized react / redux app
我很难在本地化的博客应用程序中构建数据。
我的应用程序以三种语言(英语、法语和俄语)显示带有嵌入式图片(一对多)的帖子。
访问者可以选择其区域设置。编辑者可以用三种语言编辑其帖子的本地化版本。
目前,我的商店结构如下所示:
{ 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 },
...
}
}
}
在这个阶段,我的化简器并不太臃肿,但我觉得我应该进一步规范化,以便预测何时添加与文章相关的标签、作者和其他国际化项目。
所以我正在考虑 (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},
...
}
}
"文章"、"图片"和"editStatesOfFieldsOfArticles"词典的键的最后一位数字对应于区域设置/language_id,其他数字对应于项目 ID。
我看到当我有适用于所有三种语言的商店修改时,我将从这种更扁平的结构中受益,摆脱迭代语言的需要(例如,如果我删除一篇文章,该文章应该删除所有三种语言,我目前必须做一个......在本地化的子词典和所有辅助存储的子词典上(例如"editStateOfFieldsOfArticles"(我还有其他一些这样的辅助词典))。
但是,我不完全确定我是否真的会从进一步扁平化我的哈希(以及 for...在只有三种语言需要管理的情况下,循环并不是那么成问题——此外,在我的用例中,我需要删除一篇文章并且这种删除需要反映在所有三种语言中,我仍然必须遍历三种语言数组以删除扁平化文章字典中的三个相应记录)。
此外,我担心性能问题:由于我将把我的整个集合(文章或任何其他国际化项目)存储在同一个平面树下,无论它们与什么语言相关,我担心与更结构化的树相比,对这些值的访问可能会变慢,在这种树中,我可以通过"子键控"本地化分支来访问项目 - 事实上, 后端数据库将本地化的文章存储在不同的本地化表中)。
我非常感谢任何具有为国际化内容或其他具有复杂交叉关系的商店构建 Redux 商店经验的人,他们可以就自己的经验提供一些反馈、建议或提示:- 代码可读性,特别是在化简器和记忆选择器中,- 比较嵌套树与扁平树的性能,- 进一步规范化与保持嵌套"位"的总体好处。
这个派对超级晚了,但如果你仍然好奇。
我认为您的第一个实现绝对是优越的。 超过 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 来缓存查找并制作包含区域设置的可重用查找函数。
- 通过另一个php应用程序将我的项目推送到Github存储库中
- 如何在ExtJs4应用程序上为视图、存储和模型设置自定义文件夹名称
- web浏览器中的离线应用程序存储数据并在之后上传
- 将JSON存储和恢复到此Ionic应用程序的最有效方法
- 将json数据存储在sqlite(phonegap应用程序)中
- (临时)在Web应用程序中存储JSON搜索结果
- 关闭并重新访问应用程序后,本地存储中的数据不会保留
- adal javascript windows存储应用程序令牌
- 在不同时区使用的应用程序中存储Oracle中的日期
- 手机应用程序:云存储与本地
- 在web应用程序中存储数据
- 在混合应用程序开发中使用本地存储;本地数据库“-危险或有用
- 三星智能电视视频播放器应用程序-访问存储在USB上的mp4
- 如何获取当前应用程序使用的总html5存储大小
- "未定义“角度”;在Liferay中存储的角度应用程序上执行Protractor测试时出错
- 如何在javascript应用程序JSON中存储和访问信息项
- Windows 8 javascript应用程序:如何列出应用程序存储的所有设置
- 离线移动Web应用程序存储
- 对于轻量级、可移植的基于js的web应用程序存储持久数据的最佳方法的建议
- 通过@anywhere twitter应用程序存储access_token