Reactjs商店之间的沟通

时间:2015-04-21 21:16:41

标签: javascript reactjs reactjs-flux

我开发了一个基于Reactjs和Flux的应用程序。商店之间存在沟通问题:ProjectsStoreTasksStore

getAllForCurrentProject的方法TasksStore中,我致电ProjectsStore.getCurrentId()。结果我收到Uncaught TypeError: undefined is not a functiontypeof ProjectsStore中的objectgetAllForCurrentProject。当我从任何组件中调用ProjectsStore.getCurrentId()时,它可以正常工作。

这种行为的原因是什么?

example MessageStore中询问具有相同模式的ThreadStore

getAllForCurrentThread: function() {
  return this.getAllForThread(ThreadStore.getCurrentID());
}

我的商店:

ProjectsStore.js

'use strict';

var Dispatcher = require('../dispatcher/Dispatcher');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');
var _ = require('underscore');

var Api = require('../services/Api');
var ProjectsConstants = require('../constants/ProjectsConstants');

var TasksStore = require('../stores/TasksStore');

var changeEvent = 'projectsChanged';

var current = 0;
var items = [];

function requestItems() {
    return Api.Projects.getAll();
}

function setItems(data) {
    items = data;
}

var ProjectsStore = assign({}, EventEmitter.prototype, {

    emitChange: function () {
        this.emit(changeEvent);
    },

    getAll: function () {
        return items;
    },

    getCurrentId: function() {
        return current;
    },

    getCurrent: function() {
        var item = _.where(items, { id: this.getCurrentId() });
        return (typeof item[0] == 'object' ? item[0] : null);
    },

    getChildrenOf: function(id, isInclude) {

        var result = (typeof isInclude == 'boolean' && isInclude === true ? [id] : []),
            children = _.chain(items).where({ parent: id }).pluck('id').value();

        result.concat(children);

        return result;
    }

});

ProjectsStore.dispatchToken = Dispatcher.register(function (payload) {

    var action = payload.action;

    switch (action.type) {

        case ProjectsConstants.projectsSetCurrent:
            current = action.data;
            break;

        case ProjectsConstants.projectsGetAll:
            requestItems();
            break;

        case ProjectsConstants.projectsGetAllSuccess:
            setItems(action.data);
            break;

        default:
            return true;
    }

    ProjectsStore.emitChange();

    return true;

});

module.exports = ProjectsStore;

TasksStore.js

'use strict';

var Dispatcher = require('../dispatcher/Dispatcher');
var EventEmitter = require('events').EventEmitter;
var assign = require('object-assign');
var _ = require('underscore');

var Api = require('../services/Api');
var TasksConstants = require('../constants/TasksConstants');

var ProjectsStore = require('../stores/ProjectsStore');


var changeEvent = 'tasksChanged';

var items = [];

function requestItems() {
    return Api.Tasks.getAll();
}

function setItems(data) {
    items = data;
}

var TasksStore = assign({}, EventEmitter.prototype, {

    emitChange: function () {
        this.emit(changeEvent);
    },

    getAll: function () {
        return items;
    },

    getAllForProject: function(id) {
        var projects = ProjectsStore.getChildrenOf(id, true);
        return _.chain(items).where({ parent: projects });
    },

    getAllForCurrentProject: function() {
        console.log('Type:', typeof ProjectsStore); // <-- object
        console.log('Inspect:', ProjectsStore); // <-- {}
        // Why ProjectsStore here is {} and 
        // Uncaught TypeError: undefined is not a function?
        var id = ProjectsStore.getCurrentId();
        // When I calling ProjectsStore.getCurrentId(); from any component it works fine.
        return this.getAllForProject(id);
    }

});

TasksStore.dispatchToken = Dispatcher.register(function (payload) {

    var action = payload.action;

    switch (action.type) {

        case TasksConstants.tasksGetAll:
            requestItems();
            break;

        case TasksConstants.tasksGetAllSuccess:
            setItems(action.data);
            break;

        default:
            return true;
    }

    TasksStore.emitChange();

    return true;

});

module.exports = TasksStore;

1 个答案:

答案 0 :(得分:4)

看起来你有循环依赖关系 - TasksStoreProjectsStore互相要求。

ProjectsStore不需要知道TasksStore,删除该行:

var TasksStore = require('../stores/TasksStore');

或者,如果您使用它,设计您的商店以允许依赖注入,因此您的课程不会相互依赖