Vuex - 在api调用之前或之后提交状态更改?

时间:2017-11-05 09:06:37

标签: vue.js vuejs2 vuex

我是Vue和Vuex的新手,我还不清楚我何时应该在异步事件中进行状态更改?

操作是应该调用异步操作和mutator的地方。但是,在一个动作中,我应该在异步操作之前先调用mutator(让我们说api调用保存数据),或者我应该首先调用api并在其中成功回调,调用mutator将数据更改提交到状态。

感谢。如果有人可以推荐我关于这个概念的文章,也会非常有帮助。

*有关我的问题的更多详情*

考虑以下模型,其中一个预算可以有多个预算类别



state.budgets = {
  1: {
    month: 'October',
    budgetCategories: {
      1: {
        id: 1,
        name: 'Grocery',
        budgeted: 350
      },
      2: {
        id: 2,
        name: 'Rent',
        budgeted: 1000
      },
      3: {
        id: 3,
        name: 'Utilities',
        budgeted: 150
      }
    },
    2: {
      month: 'November',
      budgetCategories: {
        1: {
          id: 1,
          name: 'Grocery',
          budgeted: 350
        },
        2: {
          id: 2,
          name: 'Rent',
          budgeted: 1000
        },
        3: {
          id: 3,
          name: 'Entertainment',
          budgeted: 100
        },
        4: {
          id: 4,
          name: 'Tuition',
          budgeted: 15000
        }
      }
    },
    ...
  }
}




假设我们想要更新一个月的特定预算类别,如下所示: state.budgets [target.key] .budgetCategories [target.categoryId] .budgeted = 200

我们有两种方法可以做到这一点:

  1. 在调用api和mutator之前,首先深入复制模型:
  2. 
    
    // mutation.js
    
    UPDATE_BUDGET_CATEGORY(state, payload) {
        state.budgets[payload.budget.id].budgetCategories[payload.budgetCategory.id] = payload.budgetCategory
    }
    
    
    

    
    
    // action.js
    export const updateBudgetCategory = ({
      commit,
      dispatch,
      getters
    }, data) {
      // deep copy the model
      let budget = { ...getters.getBudgetById(data.budget.id)
      }
      const newBudget = data.budgetCategory.budgeted
      const oldBudget = budget.budgetCategories[data.budgetCategory.id].budgeted
    
      if (oldBudget !== newBudget) {
        // update the model
        budget.budgetCategories[data.budgetCategory.id].budgeted = newBudget
    
        // api call to save the updated model
        return api.updateBudget(budget).then(
          response => {
            // commit to store state
            commit('UPDATE_BUDGET_CATEGORY', data)
          },
          error => {
            // don't commit
            console.log(error.message)
          }
        )
      }
    }
    
    
    

    优点:这是正确的顺序。存储状态中的数据与数据库中的数据一致。

    缺点:每次更新对象时都必须深度复制模型。此外,更新深度克隆模型的代码基本上与mutator中的相同。绝对看似多余而不是干。

    1. 首先提交数据更改,然后从状态检索模型以将其提交到数据库:
    2. 
      
      // action.js
      export const updateBudgetCategory = ({
        commit,
        dispatch,
        getters
      }, data) {
        // deep copy the model
        const newBudget = data.budgetCategory.budgeted
        const oldBudget = getters.getBudgetById(data.budget.id).budgetCategories[data.budgetCategory.id].budgeted
      
        if (!oldBudget !== newBudget) {
          commit('UPDATE_BUDGET_CATEGORY', data)
          //api call to save the updated model from the state
          return api.updateBudget(getters.getBudgetById(data.budget.id))
      
        }
      }
      
      
      

      优点:代码干燥清洁。我们告诉mutator发生了什么,它负责更新状态。

      缺点:那么当api调用失败时该怎么办? Vuex中是否有内置的恢复提交?

1 个答案:

答案 0 :(得分:1)

如果您要更新的状态依赖于异步调用结果,那么显然您需要等待调用完成并提交结果。

如果它与异步调用结果无关,那么您可以立即提交它。