Vuex商店的操作未执行而被调用

时间:2018-06-26 12:59:10

标签: javascript vue.js vuex

好的,因此,我有三个列表需要共同做出反应:网站,个人资料和员工。基本上,如果我选择一个站点,则只需要显示该站点的个人资料和员工,然后,如果我选择一个概要文件,则只需要显示具有该概要文件的网站和员工……依此类推。

鉴于列表已经是Vue组件,所以我继续并实现了Vuex商店来管理各种列表的内容。这是我的商店的代码:

const manageSchedulesModale = {
    state: {
        sites:[{
            id: -1,
            text: app.utils.translate("No Site"),
            icon: "site",
            selected: false
        }].concat(app.metadata.sites.map(a=>({id:a.id,text:a.name}))),
        profiles: [{
            id: -1,
            text: app.utils.translate( "No Profile" ),
            icon: "profile",
            selected: false
        }].concat (app.metadata.profiles.map(a=>(
                {
                    id: a.id,
                    text: a.name,
                    //FIXME add color tags to k-icon
                    html: "<span class='color-tag-group'><span data-color="+a.color+" class='color-tag'></span></span> "+a.name,
                    site_id: a.site_id
                }
            )
        )),
        employees: [{
            id: -1,
            text: app.utils.translate( "No Employee" ),
            icon: "user"
        }].concat(
            app.metadata.employees.map(a=>{
            var colors = a.profiles.map(a=>"<span data-color="+a.color+" class='color-tag'></span>").join("")
            return {
                id: a.id,
                text: a.firstname + " " + a.lastname,
                html: "<span class='color-tag-group'>"+colors+"</span> "+a.firstname+" "+a.lastname
            }
        })),
        currentSite: -1,
        currentProfile: -1,
        currentEmployee: -1
    },
    actions:{
        fetchProfiles(context, newSite){
            app.ajax.defaultRequest("post", "/api/profiles",{site_id: context.state.currentSite, employee_id: context.state.currentEmployee}, 
                function(response){
                let content = 
                    [{
                        id: -1,
                        text: app.utils.translate( "No Profile" ),
                        icon: "profile",
                        selected: false
                    }].concat(
                    response.data.map(
                        a =>
                            (
                                {
                                    id: a.id,
                                    text: a.name,
                                    //FIXME add color tags to k-icon
                                    html: "<span class='color-tag-group'><span data-color="+a.color+" class='color-tag'></span></span> "+a.name,
                                    site_id: a.site_id
                                }
                            )
                        )
                    );

                context.commit("reloadProfiles", content);
            });
        },

        fetchEmployees(context, newProfile)
        {

        }
    },
    mutations:{
        setCurrentSite(state, newSite){
            state.currentSite = newSite;
        },
        setCurrentProfile(state, newProfile){
            state.currentProfile = newProfile;
        },
        setCurrentEmployee(state, newEmployee){
            state.currentEmployee = newEmployee;
        },
        reloadProfiles(state, profiles){
            state.profiles = profiles;
        }
    },
    getters:{
        filterProfiles(state){
            return siteId => state.profiles.filter(profile => {
                return profile.site_id === siteId;
            });
        }
    }
};

export default new Vuex.Store({

    modules: {
        // manageSchedulesModale: manageSchedulesModale
    },
    mutations: {
        setModule(state, name){
            if(typeof state[name] === 'undefined')
            {
                this.registerModule(name, manageSchedulesModale);
            }

        }
    }
})

现在,这是我的列表的代码:

<template lang="pug">
div
    .btn.dropdown-toggle.text-left.btn-block.k-selectbox-toggle(tabindex="0", v-on:keydown.down.stop="selectDown", v-on:keydown.up.stop="selectUp", v-on:keydown.enter="updateClose")
        k-icon(:icon="currentOption.icon||icon||placeholderIcon", v-if="currentOption.icon||icon||(!currentOption.text&&placeholderIcon)")
        span(v-if="currentOption.icon||icon||(!currentOption.text&&placeholderIcon)") &nbsp;
        span(v-html="currentOption.html||currentOption.text||placeholder")
    .dropdown-menu.pre-scrollable(v-if="searchResults.length")
        .search-indicator(hidden v-if="options.length>5")
        .dropdown-header.pr-3.pl-3(v-show="options.length>5")
            input.form-control(type="text", :placeholder='__("Search...")', style="width:100%", v-model="searchText", v-on:keydown.down.stop="selectDown", v-on:keydown.up.stop="selectUp", v-on:keydown.enter.stop="updateClose()")
        //{{__("Search...")}} FIXME because poedit is retarded
        a(v-for="(option,index) in searchResults", :class="'dropdown-item '+(option.id==value?'active':'')", href="#" , v-on:mousedown="update(option.id)")
            k-icon(:icon="option.icon||icon", v-if="option.icon||icon")
            span(v-if="option.icon||icon") &nbsp;
            span(v-html="option.html||option.text")
    .dropdown-menu.pre-scrollable(v-else) 
        .dropdown-item {{__("Empty List")}}
    input(type="hidden", :name="name", :value="value")
</template>

<script>
    import { mapGetters } from 'vuex';

    var allowClose = true;

    // autofocus search in selectbox dropdowns
    $(document).on('shown.bs.dropdown', function(e){

        var searchInput = $(e.target).find('.search-indicator')

        if(searchInput.length){
            allowClose = false;
            $(e.target).find('.form-control').focus();
        }
    });

    // close on blur
    $(document).on('blur', '.k-selectbox-toggle', function(e){
        var element = $(this);

        if(allowClose){
            setTimeout(a=>{
                element.next().removeClass("show") // WHY DOES THIS WORK ?!?!?!?
            }, 100)
        }
        allowClose = true;
    });

    $(document).on('blur', '.k-selectbox-toggle+.dropdown-menu input.form-control', function(e){
        var element = $(this);

        setTimeout(a=>{
            element.parent().parent().removeClass("show") // WHY DOES THIS WORK ?!?!?!?
        }, 100);
    });

    $(document).on('focus','.k-selectbox-toggle', e => {
        $(e.target).dropdown('toggle');
    })

    // mod negative numbers
    var mod = (x, n) => ((x%n)+n)%n;

    export default {
        methods:{
            update(id){
                if(id!==undefined){
                    this.$emit('update:value', id)
                }
            },
            updateClose(e){
                if(this.searchResults[0]&&_.findIndex(this.searchResults, {id:this.value})==-1) this.$emit('update:value', this.searchResults[0].id);

                this.$emit('update:value', this.value);

                $(this.$el).find("input.form-control").blur();
                $(this.$el).find(".k-selectbox-toggle").blur();
            },
            selectDown(e){
                var index = _.findIndex(this.searchResults, {id:this.value});
                if(index==-1)index=-1;
                var length = this.searchResults.length;
                this.value = this.searchResults[(index+1)%length].id;
                e.preventDefault();
            },
            selectUp(e){
                var index = _.findIndex(this.searchResults, {id:this.value});
                if(index==-1)index=1;
                var length = this.searchResults.length;
                this.value = this.searchResults[mod(index-1, length)].id;
                e.preventDefault();
            }
        },
        computed:{
            searchResults(){
                var exclude = this.exclude||[];
                // console.log(this.filterProfiles(26));
                if(exclude[0]&&exclude[0].id){
                    exclude = exclude.map(a=>a.id)
                }
                return this.options.filter(a=>{
                    return _.lowerCase(a.text)
                        .indexOf(
                            _.lowerCase(this.searchText)
                        ) !== -1;
                }).filter(a=>exclude.indexOf(a.id) == -1);
            },
            currentOption(){

                var currentValue = _.find(this.options, {id:this.value}) || _.find(this.options, {id:-1}) || (this.placeholder?{}:this.options[0]) || {};
                var mutation = null;

                // console.log("Tobbi Filteau");
                // console.log(this.$store.state.manageSchedules);

                if(this.model == "sites")
                {
                    console.log("111;");
                    // console.log("djkflkjldflkjdsfsdlk");
                    this.$store.commit("setCurrentSite", currentValue);
                    this.$store.dispatch("fetchProfiles", currentValue);
                }
                else if(this.model == "profiles")
                {
                    console.log("222;");
                    this.$store.commit("setCurrentProfile", currentValue);
                }
                else
                {
                    console.log("333;");
                    this.$store.commit("setCurrentEmployee", currentValue);
                }

                return currentValue;
            },
            ...mapGetters(['filterProfiles'])

        },
        watch:{
            options(){
                $(this.$el).find(".dropdown-menu").removeClass("show")
            }
        }
    };

</script>

问题是我遇到了意外的行为。您会看到,在currentOption()计算属性中,我有一个“ if”,它可以帮助我确定实际触发了哪个列表。现在,如果更改员工列表的值,最终在控制台中将显示以下输出:

333
111
222

但是,如果我评论以下行:

this.$store.dispatch("fetchProfiles", currentValue);

我得到的输出实际上只有“ 333”(这是我实际上期望的)。我不明白为什么添加“调度”会触发所有三个列表中的更改,即使它甚至都不应该执行。谁能解释?

0 个答案:

没有答案