Dynami c хранение данных при вводе с laravel и vuejs - PullRequest
0 голосов
/ 27 февраля 2020

У меня многоэтапная форма на vue js. Мне нужно динамически во время ввода отправлять запросы, проверять на сервере и получать ответ для отображения ошибок проверки.

Мои данные:

data() {
    return {
        form: {...this.candidate}, // we get an object with fields already filled *
        errors: new Errors(), // object with validation errors
    }
},

Теперь для каждого ввода у меня есть вычисленное свойство:

characteristicFuturePlans: {
    get() {
        return this.form.characteristic_future_plans;
    },
    set(value) {
        this.saveField('characteristic_future_plans', value);
    }
},

Метод saveField отправляет данные:

saveField(field, value) {
    this.form[field] = value; // keep the data in the object relevant
    axios.put(`/api/candidate/${this.candidate.token}`, {[field]: value})
        .then(() => { this.errors.clear(field) })
        .catch((error) => {
            this.errors.record(field, error.response.data.errors[field]);
        });
},

Теперь при каждом изменении ввода будет отправляться запрос. Но при таком подходе, когда мы быстро набираем текст в поле, иногда отправляемый предпоследний запрос идет после последнего. Оказывается, если вы быстро напишите «Джонни», иногда запрос с текстом «Джонн» будет идти после запроса с текстом «Джонни», и неправильное значение будет сохранено в базе данных.

Тогда Я убедился, что данные были отправлены через 1 секунду после прекращения ввода текста. Добавлен timerId: {} в data () {}, а затем:

saveField(field, value) {
    if(this.timerId[field]) {
        clearTimeout(this.timerId[field]);
    }
    this.timerId[field] = setTimeout(this.send, 1000, field, value);
},
send(field, value) {
    this.form[field] = value;
    axios.put(`/api/candidate/${this.candidate.token}`, {[field]: value})
        .then(() => { this.errors.clear(field) })
        .catch((error) => {
            this.errors.record(field, error.response.data.errors[field]);
        });
},

Но теперь, если после заполнения ввода менее чем за секунду, нажмите кнопку для go до следующего шага форма, страница будет просто refre sh. (кнопка go для следующего шага отправит запрос на сервер, чтобы проверить, заполнены ли обязательные поля)

Как правильно сохранить данные в базу данных при вводе текста? Могу ли я сделать это без setTimeout ()? Если так, как я могу убедиться, что данные последнего запроса, а не предпоследнего, хранятся в базе данных? Я буду рад любому совету.

Обновлено. Прикрепите некоторый код шаблона.

Часть шага [i]. vue компонент:

<div class="row">
    <div class="form-group col-md-6">
        <element-form  title="Title text" :error="errors.get('characteristic_future_plans')" required isBold>
        <input-input v-model="characteristicFuturePlans" :is-error="errors.has('characteristic_future_plans')"
            :placeholder="'placeholder text'"/>
        </element-form>
    </div>
</div>

шаблон компонента ввода-вывода:

<input :value="value" :type="type" class="form-control" :class="isErrorClass" 
       :placeholder="placeholder" @input="$emit('input',$event.target.value)">

Компоненты шагов формы вызываются из компонента Page. Рядом находится компонент кнопки для перехода к следующему шагу.

<component :is="currentStep"
           :candidate="candidate"
           // many props
           :global-errors="globalErrors"/>

<next-step :current-step="step" :token="candidate.token"
           @switch-step-event="switchStep" @throw-errors="passErrors"></next-step>

Компонент NextStep отправляет запрос на сервер, он проверяет, заполнены ли обязательные поля в базе данных. Если нет, выкиньте ошибку проверки. Если это так, go до следующего шага формы.

1 Ответ

0 голосов
/ 27 февраля 2020

вы можете попробовать просмотреть входные значения, а затем использовать _.debounce() из нижнего подчеркивания. js (sr c: https://underscorejs.org/#debounce) для задержки вызова метода, который делает запрос к серверу :

   watch: {
        fieldName: _.debounce(function(value) {
            if(value === ''){
                return;
            }
            this.saveField(this.fieldName, value);
        },
        ...
...