javascript - Správa závislosti dát obchodu v React/Flux
Mám webovú aplikáciu vyvinutú pomocou architektúry Flux od Facebooku. Stránka má dva pohľady: jeden zobrazuje zoznam úloh TODO. Druhý pohľad zobrazuje náhodnú sadu úloh TODO.
Je zjavné, že existujú dva problémy, ktoré musia byť riadené obchodmi. Prvým je zoznam dostupných úloh TODO. Druhým je zoznam náhodne vybraných položiek TODO.
Takže mám TODOStore, ktorého úlohou je výlučne spravovať dostupné TODO položky. Má akcie na loadTODOs, addTODO, deleteTODO, editTODO. Pri spustení tento store nenačíta všetky TODO položky. Chcem, aby načítal zoznam TODO položiek z databázy len keď je to potrebné.
Druhý obchod je RandomTODOListStore. Jeho zodpovednosťou je spravovať náhodne vybrané položky TODO. Zdá sa mi, že RandomTODOListStore by mal pristupovať k položkám TODO cez TODOStore, použitím 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");
}
}
Problém s týmto je, že, ako už bolo spomenuté, TODOStore nenačíta položky TODO pri spustení.
Otázka je: "Ako RandomTODOListStore zaručuje, že TODOStore už načítal položky TODO?".
Odpoveď č. 1
Navrhovaná implementácia Flux používa metódu waitFor na synchronizáciu obchodov. Vytvoril som Reflux, aby to bolo oveľa jednoduchšie a umožnil obchodom počúvať iné obchody. Efekt tejto funkcie je, že zaručí, že predchádzajúci obchod v reťazci spracoval svoje údaje.
Rozhranie je trochu odlišné, pretože Reflux sa nespolieha na reťazcové konštanty na rozlíšenie akcií, takže tu je príklad.
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();
Dúfam, že to dáva zmysel.
Odpoveď č. 2
Myslím, že toto je dôvod, prečo architektúra Flux spomína potrebu synchronizovať obchody s metódou waitFor spomenutou tu
Ak chcete synchronizovať svoje obchody, váš RandomTODOListStore by pravdepodobne mal vyzerať takto:
case Constants.LOAD_RANDOM_TODO:
Dispatcher.waitFor([TodoStore.dispatcherIndex],this.loadRandomTODO);
break;
Potom vo vašom TodoStore môžete reagovať na Constants.LOAD_RANDOM_TODO a načítať zoznam úloh, ak ešte nie sú načítané.
Avšak myslím si, že je to príliš zložité a pravdepodobne by ste nemali vytvárať ďalší obchod pre náhodné úlohy, pretože tento obchod bude (predpokladám) vždy delegovať na skutočný obchod s úlohami. Namiesto toho jednoducho použite TodoStore.getRandom()
Upraviť:
Áno, TodoStore nemusí vedieť, ako sa používa. Takže keď chcete získať náhodné todo, pravdepodobne môžete použiť tú istú udalosť, ktorú používate, napríklad Constants.LOAD_TODOS a potom získať náhodné todo z toho skladu s TodoStore.getTodos()[randomIndex]
Ak obe komponenty spustia udalosť súčasne, druhú udalosť môžete ignorovať
Ďalším riešením je, aby RandomTODOListStore reagoval na udalosť načítania a vybral niektoré úlohy z hlavného úložiska, aby ich vložil do RandomTODOListStore:
case Constants.TODOS_LOADED:
this.randomTodos = randomSubset(TodoStore.getTodos,subsetSize);
break;
Môžete sa inšpirovať asynchrónnym príkladom z Fluxxor: pre asynchrónne dáta sa nevyvoláva iba jedna udalosť, ale dve (príkaz + úspech/neúspech)
