javascript - Tallennustietojen riippuvuuden hallinta React/Fluxissa


Minulla on verkkosovellus, joka on kehitetty käyttämällä Facebookin Flux-arkkitehtuuria. Sivulla on kaksi näkymää: yksi näyttää TODO-kohteiden listan. Toinen näkymä näyttää satunnaisen joukon TODO-kohteita.

On selvästi kaksi huolta, jotka kauppojen on hallittava. Ensimmäinen on saatavilla olevien TODO-lista. Toinen on satunnaisesti valittujen TODO-kohteiden lista.

Minulla on siis TODOStore, jonka ainoa tehtävä on hallita saatavilla olevia TODO-kohteita. Sillä on toimintoja loadTODOs, addTODO, deleteTODO, editTODO. Käynnistyksen yhteydessä tämä store ei lataa kaikkia TODO-kohteita. Haluan, että se hakee TODO-kohteiden listan tietokannasta vain tarvittaessa.

Toinen kauppa on RandomTODOListStore. Sen vastuulla on hallita satunnaisesti valittuja TODO-kohtia. Minusta näyttää siltä, että RandomTODOListStore tulisi käyttää TODO-kohtia TODOStore-kautta, käyttäen 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");
    }
}

Ongelma tässä on se, että kuten aiemmin todettiin, TODOStore ei lataa TODO-kohteita käynnistyksen yhteydessä.

Kysymys on: "Miten RandomTODOListStore takaa, että TODOStore on jo hakenut TODO-kohteet?".

Vastaus #1

Ehdotettu Flux-toteutus käyttää waitFor-metodia synkronoimaan varastoja. Perustin Refluxin käsittelemään tätä paljon helpommin sallimalla varastojen kuunnella muita varastoja. Tämän ominaisuuden vaikutus on, että se takaa, että ketjun edellinen varasto on käsitellyt sen tietoja.

Käyttöliittymä on hieman erilainen, koska Reflux ei luota merkkijonovakioihin tunnistaakseen toimintoja, joten tässä on esimerkki.

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

Toivottavasti tämä on järkevää.

Vastaus #2

Mielestäni tästä syystä Flux-arkkitehtuuri mainitsee tarpeen synkronoida kaupat waitFor-menetelmällä, kuten täällä mainitaan

Jos haluat synkronoida myymäläsi, RandomTODOListStore -tietovarastosi pitäisi todennäköisesti näyttää tältä:

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

Sitten sinun TodoStore-sovelluksessasi voit reagoida Constants.LOAD_RANDOM_TODO ja ladata todo-listan, jos ne eivät ole vielä ladattuja.

Kuitenkin mielestäni tämä on liian monimutkaista, eikä sinun todennäköisesti pitäisi luoda uutta varastoa satunnaisille tehtäville, koska tämä varasto (luulisin) aina välittää oikealle tehtävävarastolle. Käytä sen sijaan TodoStore.getRandom()

Muokkaa:

Kyllä, TodoStore ei tarvitse tietää, kuinka sitä käytetään. Siksi, kun haluat saada satunnaisen to-do:n, voit todennäköisesti käyttää samaa tapahtumaa kuin käytät, kuten Constants.LOAD_TODOS ja sitten saada satunnaisen to-do:n tästä kaupasta käyttämällä TodoStore.getTodos()[randomIndex]

Jos molemmat komponentit laukaisevat tapahtuman samanaikaisesti, voit ohittaa toisen tapahtuman

Toinen ratkaisu on saada RandomTODOListStore reagoimaan ladattuun tapahtumaan ja valitsemaan joitakin päävaraston tehtäviä sijoitettavaksi RandomTODOListStoreen:

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

Voit inspiroitua Fluxxorin Async-esimerkistä: asynkroniselle datalle ei laukaista vain yhtä tapahtumaa, vaan kaksi (komento + onnistuminen/epäonnistuminen)