如何在助焊器应用

时间:2015-05-07 07:55:38

标签: javascript reactjs flux

根据Jing Chen(Facebook)的说法,他们在upcomming中继框架中实现了类似的东西:

React.js Conf 2015 - Flux Panel

我只是好奇是否有人将此类内容实现到助焊器架构中,那么心理模型是什么样的呢?据我所知,除了你的真实来源之外,你还会创建一个额外的商店"存储以保持乐观更新的状态。然后根据服务器的反馈,您可以将其从乐观商店中取出,然后将其合并到" real"存储或跳过合并并重新渲染视图。视图显示了真实来源中的内容和#34;商店以及乐观商店中的内容正是这个订单。

如果有人实施了这样的事情,那么如果你能分享你的经验和心理模型,那将会非常棒。

1 个答案:

答案 0 :(得分:1)

我也在这里寻找答案。没有运气,所以我试着弄清楚自己。

因此,如果您听听Jing在该细分中所说的内容,我不会认为您正在维护一个具有变异状态的独立商店。她说要坚持乐观的行动。她还提到,撤消这些突变是一种痛苦,而且它们是。 跟踪变异状态是敌人。

她所描述的是缓存和验证用户正在采取的操作以及这些操作如何变异状态。

因此,让我们创建一个待办事项并异步保存到服务器。目标是按照发生的顺序保存操作。每当视图要求todos时,立即应用突变。视图不会知道脏模型或保存模型之间的区别,因为它不需要。但唯一一次改变真相的来源是服务器成功或失败的反应。

// ........................
// === Add Todo Action  ===
// ^^^^^^^^^^^^^^^^^^^^^^^^
var addTodoAction = function(todo) {
    var actionId = guid();

    Dispatcher.dispatch({
        actionType: 'ADD_TODO',
        actionId: actionId,
        payload: todo
    });

    // Async Operation (save to server)
    // Callbacks for success and error
    API.addTodo(todo, function(res) {
        Dispatcher.dispatch({
            actionType: 'ADD_TODO_SUCCESS',
            actionId: actionId, // Identify the same optimistic action
            payload: res.todo
        });
    }, function(err) {
        Dispatcher.dispatch({
            actionType: 'ADD_TODO_FAILURE',
            actionId: actionId, // Identify the same optimistic action
            error: err
        });
    });
};





// ................................
// === Private Todos Collection ===
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var _todos = new Immutable.OrderedMap();

// Add todo to collection
var addTodo = function(todo) {
    _todos = _todos.set(todo.id, todo);
};


// ........................................
// === Collection of Optimistic Updates ===
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var _actions = new Immutable.OrderedMap(); // Ordered Immutable Map to preserve sequential order of mutations

// Add action to queue
var addAction = function(e) {
    _actions = _actions.set(e.actionId, e);
};

// Remove action
var removeAction = function(e) {
    _actions = _actions.delete(e.actionId);
};


// ........................................................
// === Create Mutation of Source of Truth for the View ===
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var getOptimisticTodos = function() {

    // Loop through optimistic mutations in order, and apply them to a copy of the state.
    return _.reduce(_actions.toArray(), function(todos, action) {
        switch (action.actionType) {
            case 'ADD_TODO':
                todos = todos.set(action.payload.id, action.payload);
                break;
            default:
        }
        return todos;
    }, _todos.asImmutable());

};



// ..........................................
// === Create a Public API for Todo Store ===
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var TodoStore = _.extend({}, Events, {
    getTodos: function() {
        return getOptimisticTodos();
    }
});

// ......................................
// === Register actions we care about ===
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/* Example Dispatch 
* 
*   {
*       actionId: 12345,
*       actionType: 'ADD_TODO_SUCCESS',
*       payload: {
*           id: 12345,
*           text: 'Example Todo'
*       }
*           
*   }
* 
*/

TodoStore.dispatchToken = Dispatcher.register(function(e){
    switch (e.actionType) {
        case 'ADD_TODO':
            addAction(e); // add optimistic action to queue
            TodoStore.trigger('change'); // let views know about change
            break;
        case 'ADD_TODO_SUCCESS':
            removeAction(e); // remove optimistic action because it succeeded
            addTodo(e.payload); // add todo to source of truth
            TodoStore.trigger('change'); // let views know about change
            break;
        case 'ADD_TODO_FAILURE':
            removeAction(e); // remove optimistic action because it failed
            console.log(e.error); // handle error in store or elswhere
            TodoStore.trigger('change'); // let views know about change
            break;
        default:
    }
});