2014-07-13 10 views
5

Ho una web app sviluppata con Facebook Flux Architettura. La pagina ha due viste: una mostra un elenco di oggetti TODO. La seconda vista mostra un insieme casuale di elementi TODO.negozio Managing dipendenza dati in Reagire/Flux

ci sono chiaramente due preoccupazioni che devono essere gestiti da negozi. Il primo è l'elenco dei TODO disponibili. Il secondo è l'elenco degli oggetti TODO selezionati casualmente.

Ho quindi avere un TODOStore, che è la preoccupazione è solo di gestire gli elementi TODO disponibili. Ha azioni ai loadTODOs, addTODO, deleteTODO, editTODO. All'avvio, questo negozio non carica tutti gli elementi TODO. Voglio che recuperi l'elenco di elementi TODO dal database solo quando necessario.

Il secondo negozio è il RandomTODOListStore. È responsabilità gestire gli elementi TODO selezionati casualmente. Mi sembra che lo RandomTODOListStore debba accedere agli articoli TODO attraverso lo TODOStore, usando 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"); 
    } 
} 

Il problema con questo è che, come affermato in precedenza, il TODOStore non carica le voci TODO all'avvio.

La domanda è: "? Come funziona il RandomTODOListStore garanzia che il TODOStore ha già recuperato le voci todo".

risposta

2

Credo che questo sia il motivo per cui l'architettura Flux menziona la necessità di sincronizzare i negozi con il metodo waitFor menzionate here

Se si desidera sincronizzare i vostri negozi, il vostro RandomTODOListStore dovrebbe probabilmente essere simile:

case Constants.LOAD_RANDOM_TODO: 
    Dispatcher.waitFor([TodoStore.dispatcherIndex],this.loadRandomTODO); 
    break; 

Quindi, sul tuo TodoStore, puoi rispondere a Constants.LOAD_RANDOM_TODO e caricare l'elenco di tutti i casi, se non sono ancora stati caricati.

Tuttavia penso che questo sia complicato, e probabilmente non dovresti creare un altro negozio per tutti i casi casuali in quanto questo negozio (credo) delegherà sempre al negozio reale. Basta usare TodoStore.getRandom() invece

Edit:

Sì TodoStore non ha bisogno di sapere come viene utilizzato. Così, quando si desidera ottenere un todo caso, probabilmente si può utilizzare lo stesso evento si utilizza, come Constants.LOAD_TODOS e quindi ottenere un todo caso da quel negozio con TodoStore.getTodos()[randomIndex]

Se entrambi i componenti fuoco l'evento in concomitanza, è possibile ignorare il 2 ° evento

Un'altra soluzione è quella di avere il RandomTODOListStore reagire all'evento caricato e selezionare alcuni todos del negozio principale per metterli in RandomTODOListStore:

case Constants.TODOS_LOADED: 
    this.randomTodos = randomSubset(TodoStore.getTodos,subsetSize); 
    break; 

Si può ispirare se stessi dal Async exemple from Fluxxor: per i dati asincrono , non c'è solo uno evento che viene licenziato, ma 2 (comando + successo/insuccesso)

+0

Sì, ci ho pensato. Il problema è che TODOStore non dovrebbe preoccuparsi di come gli altri lo stanno usando. Non dovrebbe dovere reagire alle azioni di RandomTODOListStore. Immagina che ogni volta che ho qualcos'altro che ha bisogno di oggetti TODO, TODOStore sta andando a gonfiarsi molto velocemente. – rafalotufo

+0

@rafalotufo vedi la mia modifica –

0

tua RandomTODOListStore deve attendere TODOStore.È possibile raggiungere questo obiettivo facilmente usando questa libreria (la mia) 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); 
    }] 

]); 

ora quando la vostra applicazione si avvia è sufficiente chiamare l'azione

TODOActions.load();

4

L'implementazione di Flux proposta utilizza un metodo waitFor per sincronizzare gli archivi. Ho creato Reflux per gestire questo molto più facilmente lasciando che i negozi siano in grado di ascoltare altri negozi. L'effetto di questa funzione è che garantirà che il precedente negozio della catena ha gestito i suoi dati.

L'interfaccia è leggermente diversa, perché Reflux non si basa sulle costanti di stringa per discernere le azioni, quindi ecco un esempio.

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(); 

Spero che questo abbia senso.

Problemi correlati