Vuex-仅在吸气剂上修改状态对象

时间:2019-02-21 16:33:46

标签: javascript vue.js vuex vue-cli-3

我有很多具有关系的状态模块,这是我的两个主要状态:

channels.js

const state = {
    channels: [
        {
            id: 1,
            name: 'E-mail'
        },
        {
            id: 2,
            name: 'SMS'
        }
    ]
}

const getters = {
    channel(state) {
        return (id) => {
            return _.find(state.channels, (channel) => {
                return channel.id == id
            })
        }
    },
    channels(state) {
        return state.channels
    }
}

wallets.js

const state = {
    wallets: [
        {
            id: 1,
            name: "Wallet A",
            channel_id: 1
        },
        {
            id: 2,
            name: "Wallet B",
            channel_id: 2
        }
    ]
}

const getters = {
    wallet(state) {
        return (id) => {
            return _.find(state.wallets, (wallet) => {
                return wallet.id == id
            })
        }
    },
    wallets(state) {
        return state.wallets
    }
}

当我呼叫吸气剂wallets/wallets而不是返回时:

[
    {
        id: 1,
        name: "Wallet A",
        channel_id: 1
    },
    {
        id: 2,
        name: "Wallet B",
        channel_id: 2
    }
]

有什么办法可以返回吗?

[
    {
        id: 1,
        name: "Wallet A",
        channel: {
            id: 1,
            name: 'E-mail'
        }
    },
    {
        id: 2,
        name: "Wallet B",
        channel: {
            id: 2,
            name: 'SMS'
        }
    }
]

编辑


基于8位答案,我尝试了以下代码,但未成功:

import {http} from "../../support/http";
import axios from "axios";

const state = {
    actions: [],
    bots: [],
    conditions: []
}

const getters = {
    action(state) {
        return (id) => {
            return _.find(state.actions, (action) => {
                return action.id == id
            })
        }
    },
    actions(state) {
        return state.actions
    },
    bot(state) {
        return (id) => {
            return _.find(state.bots, (bot) => {
                return bot.id == id
            })
        }
    },
    bots(state, getters, rootState, rootGetters) {
        return state.bots.map((bot) => {
            let channels = bot.channels.map((item) => {
                let channel = rootGetters["channels/channel"](item.channel_id)
                let wallet = rootGetters["wallets/wallet"](item.wallet_id)

                return {
                    ...item,
                    channel,
                    wallet
                }
            })

            return {
                ...bot,
                channels: channels
            }
        })
    },
    condition(state) {
        return (id) => {
            return _.find(state.conditions, (condition) => {
                return condition.id == id
            })
        }
    },
    conditions(state) {
        return state.conditions
    },
    primaryConditions(state) {
        return _.filter(state.conditions, (condition) => {
            return condition.primary == true
        })
    },
    secondaryConditions(state) {
        return _.filter(state.conditions, (condition) => {
            return condition.primary == false
        })
    }
}

const actions = {
    fetchData({dispatch}) {
        function getActions() {
            return http.get('idr/actions')
        }

        function getBots() {
            return http.get('idr/bots')
        }

        function getConditions() {
            return http.get('idr/conditions')
        }

        return axios.all([
            getActions(),
            getBots(),
            getConditions()
        ]).then(axios.spread(function (actions, bots, conditions) {
            dispatch('setActions', actions.data.data)
            dispatch('setBots', bots.data.data)
            dispatch('setConditions', conditions.data.data)
        })).catch(error => console.error(error))
    },
    insertChannel({commit}, channel) {
        commit('INSERT_CHANNEL', channel)
    },
    setActions({commit}, actions) {
        commit('SET_ACTIONS', actions)
    },
    setBot({commit}, bot) {
        commit('SET_BOT', bot)
    },
    setBots({dispatch}, bots) {
        _.each(bots, (bot) => {
            dispatch('setBot', bot)
        })
    },
    updateBot({commit}, data) {
        commit('UPDATE_BOT', data)
    },
    deleteBot({commit}, bot) {
        commit('DELETE_BOT', bot)
    },
    setConditions({commit}, conditions) {
        commit('SET_CONDITIONS', conditions)
    }
}

const mutations = {
    INSERT_CHANNEL(state, data) {
        let index = _.findIndex(state.bots, {id: data.bot_id});

        state.bots[index].channels.push(data.channel)
    },
    SET_ACTIONS(state, actions) {
        state.actions = actions
    },
    SET_BOT(state, data) {
        let index = _.findIndex(state.bots, {'id': data.id})

        index > -1 ? state.bots[index] = data : state.bots.push(data)
    },
    UPDATE_BOT(state, data) {
        let index = _.findIndex(state.bots, {id: data.bot_id});

        state.bots[index].channels = data.channels
    },
    DELETE_BOT(state, bot) {
        let bot_index = _.findIndex(state.bots, {id: bot.id});

        state.bots.splice(bot_index, 1)
    },
    SET_CONDITIONS(state, conditions) {
        state.conditions = conditions
    }
}

export default {
    namespaced: true,
    state,
    getters,
    actions,
    mutations
}

getter正确返回了数据,但是当我将特定的bot添加到data属性时,新属性消失了...

enter image description here

Bot是通过以下方式添加到数据的:

<list-item v-for="bot in botsGetter" :key="bot.id" class="white-hover">
    <dropdown class="align-center">
            <template slot="menu">
                <li><a href="#" title="" @click.prevent="editBot(bot)">Editar</a></li>
            </template>
        </dropdown>
</list-item>

editBot(bot) {
    this.$bus.$emit('hide.dropdown')

    this.editBotModal = bot
}

1 个答案:

答案 0 :(得分:2)

您可以从任何模块中的任何getter访问rootGetters,请检查Vuex API here

因此,您可以这样编写wallets吸气剂:

wallets(state, getters, rootState, rootGetters) {
  return state.wallets.map((wallet) => {
    const channel = rootGetters["channel/channel"](wallet.channel_id);

    return {
      ...wallet,
      channel
    }
  }
}

或者,如果保持状态正常化(看起来确实如此),则可以使用denormalize,但实际上可能还必须使用相同的库最初对商店进行标准化,并保留一组模式。