admin管理员组文章数量:1326626
I have a web app developed using Facebook's Flux Architecture. The page has two views: one displays a list of TODO items. The second view displays a random set of TODO items.
There are clearly two concerns that need to be managed by stores. The first is the list of available TODO's. The second is the list of randomly selected TODO items.
I thus have a TODOStore
, who's concern is solely of managing the available TODO items. It has actions to loadTODOs
, addTODO
, deleteTODO
, editTODO
. On startup, this store does not load all TODO items. I want it retrieve the list of TODO items from the database only when necessary.
The second store is the RandomTODOListStore
. It's responsibility is to manage the randomly selected TODO items. Seems to me that the RandomTODOListStore
should access the TODO items through the TODOStore
, using TODOStore.getTODOItems()
.
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");
}
}
The issue with this is that, as previously stated, the TODOStore
does not load the TODO items on startup.
The question is: "How does the RandomTODOListStore
guarantee that the TODOStore
has already retrieved the TODO items?".
I have a web app developed using Facebook's Flux Architecture. The page has two views: one displays a list of TODO items. The second view displays a random set of TODO items.
There are clearly two concerns that need to be managed by stores. The first is the list of available TODO's. The second is the list of randomly selected TODO items.
I thus have a TODOStore
, who's concern is solely of managing the available TODO items. It has actions to loadTODOs
, addTODO
, deleteTODO
, editTODO
. On startup, this store does not load all TODO items. I want it retrieve the list of TODO items from the database only when necessary.
The second store is the RandomTODOListStore
. It's responsibility is to manage the randomly selected TODO items. Seems to me that the RandomTODOListStore
should access the TODO items through the TODOStore
, using TODOStore.getTODOItems()
.
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");
}
}
The issue with this is that, as previously stated, the TODOStore
does not load the TODO items on startup.
The question is: "How does the RandomTODOListStore
guarantee that the TODOStore
has already retrieved the TODO items?".
3 Answers
Reset to default 4The proposed Flux implementation uses a waitFor
method to synchronize stores. I created Reflux to handle this much more easily by letting the stores be able to listen to other stores. The effect of that feature is that it will guarantee that the previous store in the chain has handled it's data.
The interface is a bit different, because Reflux doesn't rely on string constants to discern actions so here is an example.
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();
Hope this makes sense.
I think this is why the Flux architecture mention the need to synchronize stores with the waitFor
method mentionned here
If you want to sync your stores, your RandomTODOListStore should probably look like:
case Constants.LOAD_RANDOM_TODO:
Dispatcher.waitFor([TodoStore.dispatcherIndex],this.loadRandomTODO);
break;
Then on your TodoStore, you can react to Constants.LOAD_RANDOM_TODO
and load the list of todos if they are not loaded yet.
However I think this is overplicated, and you should probably not create another store for random todos as this store will (I guess) always delegate to the real todo store. Just use TodoStore.getRandom()
instead
Edit:
Yes TodoStore does not need to know how it is used. Thus when you want to get a random todo, you can probably use the same event you use, like Constants.LOAD_TODOS
and then get a random todo from that store with TodoStore.getTodos()[randomIndex]
If both ponents fire the event concurrently, you can ignore the 2nd event
Another solution is to have the RandomTODOListStore
react to the loaded event and select some todos of the main store to put them in the RandomTODOListStore:
case Constants.TODOS_LOADED:
this.randomTodos = randomSubset(TodoStore.getTodos,subsetSize);
break;
You can inspire yourself from the Async exemple from Fluxxor: for async data, there's not only one event that is fired but 2 (mand + success/failure)
your RandomTODOListStore needs to wait for TODOStore. You can achieve this easily using this library(mine) https://github./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);
}]
]);
now when your app starts you just need to call the action
TODOActions.load();
本文标签: javascriptManaging store data dependency in ReactFluxStack Overflow
版权声明:本文标题:javascript - Managing store data dependency in ReactFlux - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742212112a2433902.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论