有什么理由不使用操作从通量存储中获取数据吗?

Is there any reason why not to use actions to get data from a flux store?

我对视图和商店如何在不断变化中相互作用的理解一直在发展。在我看来是三种模式。

此处的代码是为 angular-flux 编写的,但我认为这些想法通常适用于 flux。

模式 1 - 存储 getter 是同步的

// Get my data from the store
data = store.get();
// If store has data then do stuff with it
if (data !== undefined) {
    handleUpdate(data);
} else { // load the data from the server
    actionCreator.getData();
}
scope.$listenTo(store, "UPDATE", function (data) {
    // Listen to updates to the data
    handleUpdate(data);
})

模式 2 - 存储 getter 是异步的

// store will call the server and get the data for you if it doesn't have it
store.get().promise().then(handleUpdate(data));
scope.$listenTo(store, "UPDATE", function (data) {
    // Listen to updates to the data
    handleUpdate(data);
})

模式 3 - 使用操作和事件从存储中获取数据,因此异步处理只发生在一个地方

scope.$listenTo(store, "UPDATE", function (data) {
    // Listen to updates to the data
    handleUpdate(data);
})
flux.dispatch("GET")

在模式 3 中,商店看起来像这样:

store.handler["GET"] = function () {
    if (this.state.data) {
        this.emit("GET", this.state.data);    
    } else {
        dataResource.get().$promise.then(function(data) {
            flux.dispatch("UPDATE", data);
        });
    }
}

store.handler["UPDATE"] = function (data) {
    this.state.set("data", data);
    this.emit("GET", this.state.data);
} 

我喜欢模式 3 因为

问题是它打破了存储只在它们改变时发出事件的想法,在这种情况下它可能会在它没有改变时发出一个事件,这样请求数据的组件就可以通过事件监听系统。

他们这样做有什么根本上的问题吗,以后会把我赶出去吗?因为它不遵循纯通量方法。

我做了类似于模式3的事情。入口应用程序调用一个动作来初始化api并调用初始数据。 Api 获取数据的操作由 api.store 处理。 api.store 是唯一为请求调用 api 的对象。 api 在收到数据时调用其他操作。这些电话由相关商店处理。

app.js

'use strict';

import React  from 'react';
import ReactDom  from 'react-dom';

import AppCtrl from './components/app.ctrl.js';
import Actions from './actions/api.Actions';
import ApiStore from './stores/Api.Store';

window.ReactDom = ReactDom;

Actions.apiInit();

ReactDom.render( <AppCtrl />, document.getElementById('react') );

api.store.js

import Reflux from 'reflux';

import Actions from '../actions/api.Actions';
import ApiFct from '../utils/sa.api';

let ApiStoreObject = {
  newData: {
    "React version": "0.14",
    "Project": "ReFluxSuperAgent",
    "currentDateTime": new Date().toLocaleString()
  },
  listenables: Actions,
  apiInit() { ApiFct.setData(this.newData); },
  apiInitDone() { ApiFct.getData(); },
  apiSetData(data) { ApiFct.setData(data); }
}
const ApiStore = Reflux.createStore(ApiStoreObject);
export default ApiStore;

sa.api.js

import request from 'superagent';

import apiActions from '../actions/api.Actions';
import saActions from '../actions/sa.Actions';

module.exports = {
  getData() { request.get('/routes/getData').end((err, res) => { this.gotData(res.body); }); },
  gotData(data) { saActions.gotData1(data); saActions.gotData2(data); saActions.gotData3(data); },
  setData(data) { request.post('/routes/setData').send(data).end((err, res) => { apiActions.apiInitDone(); }) },
};

basic.store.js

import Reflux from 'reflux';

import Actions from '../actions/sa.Actions';
import AddonStore from './Addon.Store';
import MixinStoreObject from './Mixin.Store';

function _GotData(data) { this.data1 = data; BasicStore.trigger('data1'); }

let BasicStoreObject = {
  init() { this.listenTo(AddonStore, this.onAddonTrigger); },
  data1: {},
  listenables: Actions,
  mixins: [MixinStoreObject],
  onGotData1: _GotData,
  onAddonTrigger() { BasicStore.trigger('data2'); },
  getData1() { return this.data1; },
  getData2() { return AddonStore.data2; },
  getData3() { return this.data3; }
}
const BasicStore = Reflux.createStore(BasicStoreObject);
export default BasicStore;