React / Flux应用数据结构

时间:2016-02-20 12:23:31

标签: reactjs flux

我正在构建类似Gmail的电子邮件浏览器客户端应用原型,我需要一些帮助/建议构建我的React / Flux应用。我决定使用纯Flux来更好地了解它是如何工作的。

这是一个简单的电子邮件客户端,其中包含一系列字母,按文件夹和标签分组,并且能够将字母添加到收藏夹中。

所以,我有一个LettersStore包含一系列字母。单字母数据对象看起来像这样

{
  id: 0,
  new: true, //unread
  checked: false, 
  starred: false, 
  folder: "inbox", //could be 'sent', 'spam', 'drafts'
  sender: "Sender Name",
  subject: "Re:",
  snippet: "Hello there, how are you...",
  body: "Hello there, how are you doing, Mike?",
  date: "02.19.2016 16:30",
  tags:["personal", "urgent"]
}

所以我想要实现的是让用户浏览文件夹(收件箱,发送,草稿,垃圾邮件)和过滤器(加星标,标签等)

在文件夹和过滤器中都必须有一种选择(检查)部分/全部字母的方法。视图状态取决于选择了多少个字母(Select-all复选框更新,就像在Gmail上一样)。当用户选择一个字母时,将触发Flux操作并更新应用程序的状态。

应用程序顶部的控制器视图执行对LettersStore公共方法的所有调用,并将数据作为道具传递下来,但我不确定,{{1}的公共方法是什么} 应该有。目前它有:

LettersStore

这适用于文件夹,但是当涉及过滤器时,它不再有意义,因为某个文件夹中有星号字母,我觉得这不是正确的添加内容特定方法,如areSomeLettersInFilterChecked(filterType)等。

此外,就像在Gmail中一样,必须有一种方法可以选择"已加星标"过滤器,属于"收件箱"文件夹,然后导航到"收件箱"文件夹并保持选中该字母。

也许我应该将areSomeLettersInFolderChecked之类的东西移到组件级别?

我确信这必须是一种正确的方法。提前谢谢!

1 个答案:

答案 0 :(得分:0)

不要试图将所有可能的状态和过滤器封装到你的字母对象中,而是要保持愚蠢。将其标准化并使用支持数据结构来表示其他特征。

我将其剥离为以下属性:

{
  id: 0,
  sender: "Sender Name",
  subject: "Re:",
  snippet: "Hello there, how are you...",
  body: "Hello there, how are you doing, Mike?",
  date: "02.19.2016 16:30",
  tags:["personal", "urgent"]
}

您的LetterStore可以保持不变,或者您可以使用对象或地图将字母存储在其ID中,以便以后快速查找。

现在我们需要表示我们从消息中删除的属性。

我们可以使用个人sets来确定邮件是否属于newcheckedstarred类别。

例如,要为邮件加注星标,只需将其id添加到starred集即可。

var starred = new Set();
starred.add(message.id);

您可以在以后轻松检查邮件是否已加星标。

function isStarred(message) {
  return starred.has(message.id);
}

checkedunread的模式相同。

要表示文件夹,您可能希望使用对象和集合的组合。

var folders = {
  inbox: new Set(),
  sent: new Set(),
  spam: new Set(),
  drafts: new Set()
}

将结构简化为这些集合使得设计查询变得非常容易。以下是您使用集合实现的方法的一些示例。

function checkAll() {
  messages.forEach(function(message) {
    checked.add(message.id);
  });
  return checked;
}

function isChecked(message) {
  return checked.has(message.id);
}

function inFolder(name, message) {
  return folders[name].has(message.id);
}

// is message checked and in inbox
if(isChecked(message) && inFolder('inbox', message)) {
  // do something
}

只需检查消息是否属于多个集合,就可以轻松构建复杂查询。