在模态 vue 组件表单中绑定数据库 table 值

Bind database table values inside a modal vue component form

在我的 Laravel 5.3 应用程序中,我有一个模态组件,当用户单击按钮编辑数据时会显示该组件。

模态 window 的加载是使用以下代码完成的:

<a
    href="#"
    class="btn btn-sm btn-info"
    data-toggle="modal"
    data-target="#editCountryModal"
    data-country-id="{{ countries['id'] }}"
    data-country-code="{{ countries['code'] }}"
    data-country-name="{{ countries['name'] }}"
    data-country-currency-code="{{ countries['currency_code'] }}"
    data-country-currency-name="{{ countries['currency_name'] }}"
    data-country-display="{{ countries['display'] }}"
>
    <i class="fa fa-lg fa-pencil"></i>
</a>

以上代码加载模态组件内的以下表单。

<template>
    <div class="errors"></div>

    <form method="POST" @submit.prevent="updateCountry">
        <div class="form-group">
            <label for="name">Id:</label>
            <input
                type="text"
                name="id"
                id="countryId"
                class="inputText"
                autofocus="autofocus"
                placeholder="1"
                readonly="readonly"
                v-model="formData.countryId"
            />
        </div>

        <div class="form-group">
            <label for="name">Name:</label>
            <input
                type="text"
                name="name"
                id="name"
                class="inputText"
                placeholder="Eg. India"
                required="required"
                v-model="formData.name"
            />
            <div class="error">
                <span v-if="formErrors['name']" 
                      class="text-danger"
                >
                      {{ formErrors['name'] }}
                </span>
            </div>
        </div>

        <div class="form-group">
            <label for="code">Code:</label>
            <input
                type="text"
                name="code"
                id="code"
                class="inputText"
                placeholder="Eg. IND"
                required="required"
                v-model="formData.code"
            />
            <div class="error">
                <span v-if="formErrors['code']"
                      class="text-danger"
                >
                    {{ formErrors['code'] }}
                </span>
            </div>
        </div>

        <div class="form-group">
            <label for="currency_name">Currency Name:</label>
            <input
                type="text"
                name="currency_name"
                id="currency_name"
                class="inputText"
                placeholder="Eg. Indian National Rupee"
                required="required"
                v-model="formData.currency_name"
            />
            <div class="error">
                <span v-if="formErrors['currency_name']"
                      class="text-danger"
                >
                    {{ formErrors['currency_name'] }}
                </span>
            </div>
        </div>

        <div class="form-group">
            <label for="currency_code">Currency Code:</label>
            <input
                type="text"
                name="currency_code"
                id="currency_code"
                class="inputText"
                placeholder="Eg. INR"
                required="required"
                v-model="formData.currency_code"
            />
            <div class="error">
                <span v-if="formErrors['currency_code']"
                      class="text-danger"
                >
                    {{ formErrors['currency_code'] }}
                </span>
            </div>
        </div>

        <div class="form-group">
            <label for="display">Display:</label>
            <select name="display"
                    id="display" 
                    class="selectText" 
                    required="required" 
                    v-model="formData.display"
            >
                <option value="Disabled" selected="selected">Disabled</option>
                <option value="Enabled">Enabled</option>
            </select>
            <div class="error">
                <span v-if="formErrors['display']"
                      class="text-danger"
                >
                    {{ formErrors['display'] }}
                </span>
            </div>
        </div>

        <button type="submit" class="button button--teal">Edit</button>
    </form>
</template>
<script>
    export default {
        data() {
            return {
                formData: {
                    countryId: '',
                    name: '',
                    code: '',
                    currency_name: '',
                    currency_code: '',
                    display: ''
                },
                formErrors: {},
                allCountries: []
            }
        },

        ready: function() {
            this.fetchAllCountries();
        },

        methods: {
            notify: function(mType, mTitle, mMessage, nDelay) {
                $.iGrowl({
                    type: mType == 'success' ? 'success' : 'error',
                    title: mTitle,
                    message: mMessage,
                    icon: mType == 'success' ? 'steadysets-checkmark !' : 'feather-cross',
                    delay: nDelay,
                    animShow: 'bounceInRight',
                    animHide: 'bounceOutRight'
                });
            },

            fetchAllCountries: function() {
                $.get('/api/all-countries', function(countries) {
                    this.allCountries = countries;
                }.bind(this), 'json');
            },

            updateCountry: function(e) {
                $('.button').addClass('button--disabled')
                            .html('<i class="fa fa-spinner fa-spin"></i> Editing...');
                $(document).find('i.fa.fa-spinner.fa-spin').show();

                this.$http
                    .post('/admin/settings/update-country/' + this.formData.countryId, this.formData)
                    .then((result) => {
                        var res = result.data;

                        $('.button').removeClass('button--disabled').html('Edit');
                        $(document).find('i.fa.fa-spinner.fa-spin').hide();

                        // 3000 is the number of seconds before disappearing
                        this.notify(res.status, res.title, res.message, 3000);
                    },
                    (err) => {
                        $('.button').removeClass('button--disabled').html('Edit');
                        $(document).find('i.fa.fa-spinner.fa-spin').hide();

                        if ( err.status === 422 ) {
                            var errors = err.data;
                            this.formErrors = errors;

                        }
                });

                return false;
            }
        }
    }
</script>

发生的事情是,每当我提交上述表格时,提交的表格根本没有任何值。意思是我得到上面所有字段的空字符串。但是,如果我手动转到每个字段,它会以正确的字段值提交。

我希望只要用户点击提交按钮,值就应该得到更新。这意味着不应强迫用户点击每个字段,以便 vue 可以识别它。

编辑 1:

我是这样称呼模态的:

@section('pageScripts')
    <script>
        $('#editCountryModal').on('show.bs.modal', function(e) {
            var link = $(e.relatedTarget);

            var id            = link.data('country-id');
            var name          = link.data('country-name');
            var code          = link.data('country-code');
            var currency_name = link.data('country-currency-name');
            var currency_code = link.data('country-currency-code');
            var display       = link.data('country-display');

            var modal = $(this);
            modal.find('.modal-title').html('Edit Country: ' + name);
            modal.find('.modal-body #countryId').val(id);
            modal.find('.modal-body #name').val(name);
            modal.find('.modal-body #code').val(code);
            modal.find('.modal-body #currency_name').val(currency_name);
            modal.find('.modal-body #currency_code').val(currency_code);
            modal.find('.modal-body #display').val(display);
        });

    </script>
@endsection

底线问题:如果用户仅单击提交按钮,我如何提交表单的默认值(加载到模态 window)?

非常感谢任何帮助。谢谢

您正在使用 Jquery 和 Vue 的组合,这可能会导致兼容性问题,因为 Jquery 无法访问 Vue 内部对象结构。正如 Sam 所说,VueStrap 是寻找重构的好地方。

另一种选择是存储 Vue 根并使用 $broadcast 向您的表单发送一个事件,该事件将数据传播到模型而不是设置 dom 对象值。

@section('pageScripts')
    <script>
        $('#editCountryModal').on('show.bs.modal', function(e) {
            var object = {
                countryId:      link.data('country-id'),
                name:           link.data('country-name'),
                code:           link.data('country-code'),
                currency_name:  link.data('country-currency-name'),
                currency_code:  link.data('country-currency-code'),
                display:        link.data('country-display')
            };

            window.Vm.$broadcast('fillModal', object);
        });
    </script>
@endsection

其中 window.Vm 是您全局存储的根节点,因此您的 vue 初始化将进行 window.Vm = new Vue({...})

您的组件结构如下所示:

<script>
    export default {
        data() {
            return {
                formData: {
                    countryId: '',
                    name: '',
                    code: '',
                    currency_name: '',
                    currency_code: '',
                    display: ''
                },...
            }
        },
        ready: function() {...},
        methods: {...},
        events: {
            "fillModal": function(object){
                this.formData = object;
            }
        }
    }
</script>