Laravel,VueJS - 在拖放时保持 2 个数组同步

Laravel, VueJS - keeping 2 arrays in sync while dragging & dropping

我目前有引用 vuejs 包的代码来处理拖放,它正在运行。

包:

我有一系列复选框项目都绑定到一个名为“choices”的 v-model。

模板代码片段:

        <div class="form-group">  // One of the labels for the checkboxes...
            <div class="col-sm-2" style="text-align: center">
                <label class="control-label">@lang('messages.fields.category')</label>
                @include('v1.parts.tooltip', ['title' => trans('messages.admin.api.api_info_cat')])
            </div>

            // Other labels for checkboxes not shown
        </div>
        <div class="form-group">  // One of the checkboxes... others not shown
            <div class="col-sm-2">
                <input type="checkbox" class="form-control input-sm" v-model="choices"
                       id="{{ trans('messages.fields.category') }}"
                       value="{{ trans('messages.fields.category') }}"
                       name="category">
            </div>
            // Other  checkboxes not shown

    <div class="col-sm-4">
        <p>
            @lang('messages.admin.api.api_instr2')
        </p>

       // This is the portion to the right of screenshot, populated as boxes are checked

        <draggable tag="ul" v-model="choices" @start="drag=true" @end="drag=false" handle=".handle">
            <div class="list-group-item" v-for="choice in choices">
                @{{ choice }} <i class="handle fas fa-arrows-alt pull-right"></i>
            </div>
        </draggable>

    </div>

复选框值目前是人类可读的英语(尽管目前正在使用本地化)单词,选中后会显示在列表中,然后可以拖放该列表以进行手动排序。当复选框被选中时 and/or 列表被排序,标记为“事件文本”的红色文本(屏幕截图)更新。

我想保留该功能(使用人类可读的项目以便显示它们),但我也想在一个数组中有一组对应的值来保存单个单词名称(也称为变量名称)为了更容易参考,处理本地化,以及我应用程序的另一个区域中的其他处理。

所以我希望两个数组根据用户对正在拖放的数组执行的操作保持同步。

我希望我正在努力实现的目标是有意义的。替代方案——解析当前的英语单词——是可能的,但一旦引入本地化就会中断,因为那样显示的单词将不是英语。

提前致谢。

我已将此问题保持打开状态 17 天,并且一直在处理该问题。我发布了我想出的解决方案,以帮助将来可能 运行 参与其中的任何人 AND/OR 以提示任何有可能更有效的更好想法的人。

我重构了代码以管理这段模板代码中复选框的显示:

            <div class="form-group">
                <div v-for="item in checkbox_list" class="col-sm-2" style="text-align: center">
                    <label class="control-label">@{{ item.value }}</label>
                    <a v-if="item.instr" data-toggle="tooltip" :title="item.instr" data-placement="top">
                        <i class="fas fa-info-square purple"></i>
                    </a>
                </div>
            </div>
            <div class="form-group">
                <div v-for="item in checkbox_list" class="col-sm-2">
                    <input type="checkbox" class="form-control input-sm" v-model="choices"
                           :id="item.id"
                           :value="item.value"
                           :name="item.id">
                </div>
            </div>

我的Vue代码如下:

    new Vue({
        el: '#el',
        data: {
            admin_props: @json($admin_props),
            separator: '{{ $org_props[0]->value }}',
            header: '{{ $org_props[1]->value }}',
            choices: [],
            drag: false,
            checkbox_list: [
                {sort: 0, checked: 0, value: "@lang('messages.fields.category')", id: "category", instr: '@lang('messages.admin.api.api_info_cat')'},
                {sort: 0, checked: 0, value: "{!! trans_choice('messages.headers.et', 1) !!}", id: "et", instr: '@lang('messages.admin.api.api_info_et')'},
                {sort: 0, checked: 0, value: "@lang('messages.admin.api.api_times')", id: "api_times"},
                {sort: 0, checked: 0, value: "@lang('messages.headers.pdu_detail')", id: "pdu_detail"},
                {sort: 0, checked: 0, value: "@lang('messages.fields.memprice')", id: "memprice"},
                {sort: 0, checked: 0, value: "@lang('messages.fields.nonprice')", id: "nonprice"},
            ],
        },

        mounted: function () {
            this.choices = this.admin_props[1].value.split(' ' + this.separator + ' ',);
            this.varArray_update();
        },

        watch: {
            choices: function () {
                this.admin_props[1].value = this.choices.join(' ' + this.separator + ' ');
                this.api_update('header', this.admin_props[1].value);
                this.varArray_update();
            }
        },
        methods: {
            api_update: function (name, value) {

                axios.post('/panel/update', {
                    name: name,
                    value: value,
                })
                    .catch(error => console.log(error.response));
            },

            varArray_update: function() {
                var index = 0;
                this.checkbox_list.forEach(e => {
                    e.checked = 0;
                    e.sort = 0;
                });

                this.choices.forEach(element => {
                    index += 1;
                    console.log(index, element);
                    var x = this.checkbox_list.filter(function(ele) {
                        if(ele.value == element) {
                            ele.checked = 1;
                            ele.sort = index;
                        }
                    });
                });
                var out = [];
                var array_copy = this.checkbox_list;
                array_copy = array_copy.filter(function(v){ return v.checked == 1; });
                array_copy.sort((a, b) => (a.sort > b.sort) ? 1 : -1);
                array_copy.forEach(function(v) { out.push(v.id); });
                var id_hdr = out.join(this.separator);
                this.api_update('var_array', id_hdr);
            },
        }
    });

选择数组由 Vue 包 auto-managed 进行排序,当它通过 drag/drop UI 更新时,排序顺序等得到维护(如预期)。

因为我需要用与显示名称关联的相应变量名来复制它,所以我设置了 checkbox_list object 来存储 name/value 对并添加到选中状态、排序顺序和说明(仅在显示器初始设置期间使用的说明文本)

我有一个关于选项的手表设置,它更新了 header(用于显示)和 checkbox_list 数组。然后,我操作该数组的副本以获取根据选项中相应显示值排序的变量名数组。

如果有更有效的方法来做到这一点,我很想听听。