React/Flux 应用数据结构
React/Flux app data structure
我正在构建一个 Gmail-like 电子邮件浏览器客户端应用程序原型,我需要一些 help/advice 来构建我的 React/Flux 应用程序。我决定使用纯 Flux 来更好地了解它的工作原理。
这是一个简单的电子邮件客户端,带有一个字母列表,按文件夹和标签分组,并且能够将字母添加到收藏夹。
所以,我有一个包含字母数组的 LettersStore
。单个字母数据 object 看起来像这样
{
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(检查)some/all 个字母。视图状态取决于 selected 的字母数量(Select-all 复选框更新,就像在 Gmail 上一样)。当用户 select 发送一封信时,将触发 Flux 操作并更新应用程序的状态。
应用程序顶部的 controller-view 执行对 LettersStore
public 方法的所有调用并将数据作为道具向下传递,但我不确定,什么 public LettersStore
应该有的方法。目前它有:
emitChange()
addChangeListener()
removeChangeListener()
getAll() //returns array
areSomeLettersInFolderChecked(folderName) //returns bool
areAllLettersInFolderChecked(folderName) //returns bool
countNewLettersInAllFolders() //returns object
这适用于文件夹,但是当涉及到过滤器时,它就不再有意义了,因为加星号的字母在某个文件夹中,我觉得添加像 areSomeLettersInFilterChecked 这样的特定方法是不正确的(filterType) 等
此外,就像在 Gmail 中一样,必须有一种方法可以在属于 "Inbox" 文件夹的 "Starred" 过滤器中找到 select 信件,然后导航至 "Inbox" 文件夹并保留该字母 selected.
也许我应该将 areSomeLettersInFolderChecked-like 内容移动到组件级别?
我确定这一定是一种正确的方法。提前致谢!
与其尝试将所有可能的状态和过滤器封装到您的字母对象中,不如让它保持愚蠢。对其进行规范化,并使用支持的数据结构来表示其他特征。
我将其简化为以下属性:
{
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 来确定一条消息是否属于 new
、checked
和 starred
类别。
例如,要给消息加注星标,只需将其 id
添加到 starred
集。
var starred = new Set();
starred.add(message.id);
稍后您可以轻松查看消息是否已加星标。
function isStarred(message) {
return starred.has(message.id);
}
checked
和 unread
的模式相同。
要表示文件夹,您可能希望结合使用对象和集合。
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
}
构造复杂的查询变得容易,只需检查消息是否属于多个集合。
我正在构建一个 Gmail-like 电子邮件浏览器客户端应用程序原型,我需要一些 help/advice 来构建我的 React/Flux 应用程序。我决定使用纯 Flux 来更好地了解它的工作原理。
这是一个简单的电子邮件客户端,带有一个字母列表,按文件夹和标签分组,并且能够将字母添加到收藏夹。
所以,我有一个包含字母数组的 LettersStore
。单个字母数据 object 看起来像这样
{
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(检查)some/all 个字母。视图状态取决于 selected 的字母数量(Select-all 复选框更新,就像在 Gmail 上一样)。当用户 select 发送一封信时,将触发 Flux 操作并更新应用程序的状态。
应用程序顶部的 controller-view 执行对 LettersStore
public 方法的所有调用并将数据作为道具向下传递,但我不确定,什么 public LettersStore
应该有的方法。目前它有:
emitChange()
addChangeListener()
removeChangeListener()
getAll() //returns array
areSomeLettersInFolderChecked(folderName) //returns bool
areAllLettersInFolderChecked(folderName) //returns bool
countNewLettersInAllFolders() //returns object
这适用于文件夹,但是当涉及到过滤器时,它就不再有意义了,因为加星号的字母在某个文件夹中,我觉得添加像 areSomeLettersInFilterChecked 这样的特定方法是不正确的(filterType) 等
此外,就像在 Gmail 中一样,必须有一种方法可以在属于 "Inbox" 文件夹的 "Starred" 过滤器中找到 select 信件,然后导航至 "Inbox" 文件夹并保留该字母 selected.
也许我应该将 areSomeLettersInFolderChecked-like 内容移动到组件级别?
我确定这一定是一种正确的方法。提前致谢!
与其尝试将所有可能的状态和过滤器封装到您的字母对象中,不如让它保持愚蠢。对其进行规范化,并使用支持的数据结构来表示其他特征。
我将其简化为以下属性:
{
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 来确定一条消息是否属于 new
、checked
和 starred
类别。
例如,要给消息加注星标,只需将其 id
添加到 starred
集。
var starred = new Set();
starred.add(message.id);
稍后您可以轻松查看消息是否已加星标。
function isStarred(message) {
return starred.has(message.id);
}
checked
和 unread
的模式相同。
要表示文件夹,您可能希望结合使用对象和集合。
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
}
构造复杂的查询变得容易,只需检查消息是否属于多个集合。