假设我有一个 TodoStore。TodoStore 负责保存我的 TODO 项目。Todo 项目存储在数据库中。
我想知道将所有待办事项加载到商店的推荐方法是什么,以及视图应如何与商店交互以在启动时加载待办事项。
第一个替代方法是创建一个loadTodos
操作,该操作将从数据库中检索 Todos 并发出一个TODOS_LOADED
事件。然后视图将调用该loadTodos
操作,然后侦听该TODOS_LOADED
事件,然后通过调用来更新自己TodoStore.getTodos()
。
另一种选择是没有一个loadTodos
动作,并且有一个TodoStore.getTodos()
将返回一个带有现有 TODO 项目的承诺。如果 TodoStore 已经加载了 TODO 项,它只是返回它们;如果没有,那么它将从数据库中查询并返回检索到的项目。在这种情况下,即使商店现在已经加载了 TODO 项,它也不会发出 TODOS_LOADED 事件,因为getTodos
它不是一个动作。
function getTodos() {
if (loaded)
return Promise.resolve($todoItems);
else
return fetchTodoItemsFromDatabase().then(todoItems) {
loaded = true;
$todoItems = todoItems;
return $todoItems;
});
}
我相信很多人会说这破坏了 Flux 架构,因为该getTodos
函数正在更改存储状态,而存储状态只能通过调度程序发送的操作来更改。
但是,如果您认为 TodoStore 的状态是数据库中现有的 TODO 项,那么getTodos
并没有真正改变任何状态。TODO 项完全相同,因此不需要更新或通知视图。唯一的问题是,现在 store 已经取回了数据,所以现在缓存在 store 中。从 View 的角度来看,它不应该真正关心 Store 是如何实现的。它不应该真正关心商店是否仍然需要从数据库中检索数据。所有视图关心的是他们可以使用 Store 来获取 TODO 项,并且当创建、删除或更改新的 TODO 项时,Store 会通知他们。
因此,在这种情况下,视图应该只调用 TodoStore.getTodos() 以在加载时呈现自己,并在 TODO_CHANGE 上注册一个事件处理程序,以便在由于添加、删除或更改而需要更新自己时得到通知。
您如何看待这两种解决方案。他们还有其他解决方案吗?