【问题标题】:React/Flux app data structureReact/Flux 应用数据结构
【发布时间】:2016-06-02 01:58:22
【问题描述】:

我正在构建一个类似 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"]
}

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

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

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

emitChange()
addChangeListener()
removeChangeListener()

getAll() //returns array
areSomeLettersInFolderChecked(folderName) //returns bool
areAllLettersInFolderChecked(folderName) //returns bool

countNewLettersInAllFolders() //returns object

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

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

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

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

【问题讨论】:

    标签: reactjs flux


    【解决方案1】:

    与其试图将所有可能的状态和过滤器封装到你的字母对象中,不如让它保持沉默。对其进行规范化并使用支持数据结构来表示其他特征。

    我会将其简化为以下属性:

    {
      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
    }
    

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

    【讨论】:

      猜你喜欢
      • 2016-06-29
      • 1970-01-01
      • 2015-07-08
      • 2015-09-09
      • 1970-01-01
      • 2019-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-10-16
      相关资源
      最近更新 更多