【问题标题】:Flux eventemitter通量事件发射器
【发布时间】:2016-03-31 20:04:10
【问题描述】:

我目前正在尝试 FLUX 设计模式,但偶然发现了一个问题。在这个项目中,我也使用 ReactJS 来配合它。它工作正常,几乎完成了,但搞砸了。因此,我使用我呈现的按钮启动函数,单击它会触发函数链。

    render: function(){
     return (
        <div><button onClick={this.waiting}>Hello</button>
            {this.state.results}
        </div>
    )
   }

您现在可以看到,当单击此按钮时,它会触发一个名为 waiting() 的函数,其中包含以下内容

waiting: function() {
    actions.trending();
    return this.state.results;
},

所以它会触发函数并发生以下情况

    var actions = {
    trending: function(){
        api.trending()
        .then(function(result){
                dispatcher.dispatch({
                    actionType: actionConstants.TRENDING_RESULT,
                    results: result
                });
        }, function(error){
            console.log(error);
            dispatcher.dispatch({
                actionType: actionConstants.ERROR,
                error: error
            });
        });
    }   
};

一切正常,我正在获取我的数据,到目前为止我很高兴,问题是接下来会发生什么,当调度程序将 actionType 与数据一起发送时,它会进入我拥有的商店。然后在我的存储文件中注册有效负载(操作)。

    dispatcher.register(function(action){
    switch (action.actionType) {
        case actionConstants.TRENDING_RESULT:
            console.log(action.results); <- I can actually see my data
            results = action.results;
            resultErrors = null;
            SearchStore.emit(actionConstants.TRENDING_RESULT); <- Error
            break;
        case actionConstants.ERROR:
            results = null;
            resultErrors = action.error;
            console.log(resultErrors);
            SearchStore.emit(actionsConstants.ERROR);
            break;
    }
});

因此,此时我可以在 console.log 中看到我的数据,但在发出如下声音的函数中出现错误

Uncaught (in promise) TypeError: this._events[evt].push

对于我的商店功能,我使用以下内容

    var SearchStore = {
    getTrending: function() {
        return JSON.stringify(results); 
    },
    getError: function() {
        return resultErrors;
    },
    emit: function(event) {
        eventEmitter.on(event);
    },
    on: function(event, callback) {
        eventEmitter.on(event, callback);
    },
    removeListener: function(event, callback) {
        eventEmitter.removeListener(event, callback);
    }
};

最后为了接收任何发射,我在 ComponentDidMount 中调用我的 on 函数,看起来像这样

    componentDidMount: function(){
    SearchStore.on(actionConstants.TRENDING_RESULT, this.loadResults());
    SearchStore.on(actionConstants.ERROR, this.showError());
},

componentWillUnmount: function(){
    SearchStore.removeListener(actionConstants.TRENDING_RESULT, this.loadResults());
    SearchStore.removeListener(actionConstants.ERROR, this.showError());
},

对于调度程序,我使用 Facebook 的 FLUX 调度程序,对于发射器,我使用 eventemitter3。一切都很顺利,直到我尝试发出 TRENDING_RESULT 和有效载荷。对于这个问题的篇幅,我感到非常抱歉,但我想尽可能详尽,以便您理解。

【问题讨论】:

    标签: node.js reactjs flux eventemitter


    【解决方案1】:

    事件发射器应该调用 emit 函数而不是 on 函数。 所以应该是这样的:

     var SearchStore = {
        getTrending: function() {
            return JSON.stringify(results); 
        },
        getError: function() {
            return resultErrors;
        },
        emit: function(event) {
            eventEmitter.emit(event); // HERE!!
        },
        on: function(event, callback) {
            eventEmitter.on(event, callback);
        },
        removeListener: function(event, callback) {
            eventEmitter.removeListener(event, callback);
        }
    };
    

    【讨论】:

    • 谢谢您,先生,我正在按照一个示例出现错误。我从来没有注意到他也在他的发射函数中使用了 eventEmitter.emit(event) 但是我删除了那个函数并重新构建了我的代码。我将在下面发布我的解决方案。感谢您的宝贵时间!
    • 不客气。如果可以,请将问题设置为“已回答”,这对其他人有帮助。
    【解决方案2】:

    我的解决方案如下:

    'use strict';
    
    var dispatcher = require('../dispatcher/dispatcher');
    var EventEmitter = require('events').EventEmitter;
    var ObjectAssign = require('object-assign');
    var actionConstants = require('../constants/actionConstants');
    
    var _store = {
        list: [],
        error: [],
        genres: [],
        playlists: []
    }
    var resultErrors = null;
    var CHANGE_EVENT = 'change';
    
    var SearchStore = ObjectAssign( {}, EventEmitter.prototype, {
        getTrending: function() {
            return _store;
        },
        getError: function() {
            return _store;
        },
        addChangeListener: function(callback){
            this.on(CHANGE_EVENT, callback);
        },
        removeListener: function(callback) {
            this.removeListener(CHANGE_EVENT, callback);
        },
        getGenres: function() {
            return _store;
        },
        getPlaylists: function() {
            return _store;
        }
    });
    
    dispatcher.register(function(action){
        switch (action.actionType) {
        case actionConstants.TRENDING_RESULT:
            action.results.map(function(item){
                _store.list.push(item);
            });
            resultErrors = null;
            SearchStore.emit(CHANGE_EVENT);
            break;
        case actionConstants.SEARCH_RESULT:
            _store.list = [];
            console.log(_store.list);
            action.results.map(function(item){
                _store.list.push(item);
            });
            resultErrors = null;
            SearchStore.emit(CHANGE_EVENT);
            break;
        case actionConstants.ERROR:
            results = null;
            _store.error.push(action.error);
            SearchStore.emit(CHANGE_EVENT);
            break;
        case actionConstants.ADD_GENRE:
            _store.genres.push(action.index);
            SearchStore.emit(CHANGE_EVENT);
            break;
        case actionConstants.REMOVE_GENRE:
            _store.genres = _store.genres.filter(function(index){
                return index !== action.index;
            });
            console.log(_store.genres);
            SearchStore.emit(CHANGE_EVENT);
            break;
        case actionConstants.SAVE_PLAYLIST:
            var playlists = {
                "name": action.index,
                "items": {}
            }
            ;
            _store.playlists.push(playlists);
            SearchStore.emit(CHANGE_EVENT);
            break;
        default:
        }
    });
    

    所以我把我的“发射”和“开启”函数一起去掉了,并创建了一个 addChangeListener。所以我直接从我的开关盒发射,因为“发射”已经是一个函数,我不需要为“发射”函数创建一个函数。我只是使用我的监听器来接收 CHANGE_EVENT,然后它会运行一个回调函数。示例:

    componentDidMount: function(){
        SearchStore.addChangeListener(this.loadPlaylists);
    },
    
    componentWillUnmount: function(){
        SearchStore.removeListener(this.loadPlaylists);
    },
    

    因为它现在可以完美运行,我知道如果我仔细查看我的代码,我可以省去麻烦,但是你学的越多,对吗?无论如何,再次感谢您的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多