Vuex - изменяет объекты состояния только на геттерах - PullRequest
0 голосов
/ 21 февраля 2019

У меня много модулей состояний с отношениями, вот два из моих основных состояний:

channel.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 вместо return:

[
    {
        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
}

Получатель корректно возвращает данные, но когда я добавляю конкретного бота в свойство данных, новые свойства исчезают...

enter image description here

Бот добавляется к данным следующим образом:

<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 голосов
/ 21 февраля 2019

У вас есть доступ к rootGetters из любого геттера в любом модуле, проверьте Vuex API здесь .

Чтобы вы могли написать свой wallets геттер так:

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

    return {
      ...wallet,
      channel
    }
  }
}

Или, в качестве альтернативы, если вы сохраняете свое состояние нормализованным (что, как вам кажется), тогда вы можете использовать денормализовать , но вам, возможно, придется фактически первоначально нормализовать хранилище, используя ту же библиотеку, исохранить набор схем.

...