我有一个使用Facebook的Flux架构开发的网络应用程序。该页面有两个视图:一个显示TODO项目列表。第二个视图显示一组随机的TODO项目。
显然,商店需要管理两个问题。第一个是可用的TODO列表。第二个是随机选择的TODO项目列表。
因此我有一个TODOStore
,他们只关心管理可用的TODO项目。它包含loadTODOs
,addTODO
,deleteTODO
,editTODO
的操作。在启动时,此商店不会加载所有TODO项目。我希望它仅在必要时从数据库中检索TODO项目列表。
第二家商店是RandomTODOListStore
。它的职责是管理随机选择的TODO项目。在我看来,RandomTODOListStore
应使用TODOStore
通过TODOStore.getTODOItems()
访问TODO项目。
function RandomTODOListStore() {
var $randomTODOs = [];
dispatcher.register(function(payload) {
var action = payload.action;
switch (action.actionType) {
case Constants.LOAD_RANDOM_TODO:
loadRandomTODO();
break;
}
});
function loadRandomTODO() {
$randomTODOs = selectRandom(TODOStore.getTODOList());
emit("change");
}
}
问题在于,如前所述,TODOStore
在启动时不会加载TODO项目。
问题是:" RandomTODOListStore
如何保证TODOStore
已经检索过TODO项?" 。
答案 0 :(得分:4)
建议的Flux实现使用waitFor
方法来同步商店。我创建Reflux以便通过让商店能够收听其他商店来更轻松地处理这个问题。该功能的作用是它将保证链中的前一个商店已经处理了它的数据。
界面有点不同,因为Reflux不依赖于字符串常量来识别动作,所以这里是一个例子。
var TodoActions = Reflux.createActions(['load']);
var todoStore = Reflux.createStore({
init: function() {
// Listen to the load action
this.listenTo(TodoActions.load, this.loadActions);
},
loadActions: functions() {
var loadedActions = [];
// load your actions into loadedActions
// and do then the following inside the ajax
// callback when it is done:
this.trigger(loadedActions);
}
});
var randomTodoStore = Reflux.createStore({
init: function() {
// You may listen to stores as well
this.listenTo(todoStore, onLoadedActions);
},
onLoadedActions: function(loadedActions) {
// loaded actions will be passed in from the
// dotoStores change event trigger
// you may do your select random from loaded
// actions list
}
});
// Invoke the action
TodoActions.load();
希望这是有道理的。
答案 1 :(得分:2)
我认为这就是为什么Flux架构提到需要使用waitFor
提到的case Constants.LOAD_RANDOM_TODO:
Dispatcher.waitFor([TodoStore.dispatcherIndex],this.loadRandomTODO);
break;
方法同步商店
如果要同步商店,您的RandomTODOListStore可能应该如下所示:
Constants.LOAD_RANDOM_TODO
然后在您的TodoStore上,您可以对TodoStore.getRandom()
作出反应并加载待办事项列表(如果尚未加载)。
但是我认为这是过于复杂的,你可能不应该为随机待办事项创建另一个商店,因为这个商店将(我猜)总是委托给真正的todo商店。只需使用Constants.LOAD_TODOS
代替
修改强>:
是TodoStore不需要知道它是如何使用的。因此,当您想要获得随机待办事项时,您可以使用您使用的相同事件,例如TodoStore.getTodos()[randomIndex]
,然后通过RandomTODOListStore
如果两个组件同时触发事件,则可以忽略第二个事件
另一个解决方案是让case Constants.TODOS_LOADED:
this.randomTodos = randomSubset(TodoStore.getTodos,subsetSize);
break;
对加载的事件做出反应并选择主存储的一些待办事项以将它们放入RandomTODOListStore中:
{{1}}
你可以从here启发自己:对于异步数据,不仅有一个事件被触发而是2(命令+成功/失败)
答案 2 :(得分:0)
您的RandomTODOListStore需要等待TODOStore。您可以使用此库(我的)https://github.com/kjda/ReactFlux
轻松实现此目的var ReactFlux = require('react-flux');
var TODOConstants = ReactFlux.createConstants(['LOAD'], 'TODO');
var TODOActions = ReactFlux.createActions({
load: [TODOConstants.TODO_LOAD, function(){
//load your todos here
return { todos: [{title: 'do this'}, {title: 'do that'}]}
}]
});
var TODOStore = ReactFlux.createStore({
getTodos: function(){
return this.getState().todos;
}
}, [
[TODOConstants.TODO_LOAD_SUCCESS, function(payload){
this.setState({
todos: payload.todos
});
}]
]);
var RandomTODOListStore = ReactFlux.createStore({
selectRandomFromList: function(todos){
//..... select some here
}
}, [
/**
* This waits for TODOStore to process the message first
*/
[TODOConstants.TODO_LOAD_SUCCESS, [TODOStore], function(payload){
this.selectRandomFromList(payload.todos);
}]
]);
现在,当您的应用启动时,您只需要调用操作
TODOActions.load();