@hypertonyc

Vuejs. Как активировать кнопку «сохранить» при изменении какого-либо поля?

<template>
<div class="row">
        <div class="col-md-4">
          <div class="list-group">
            <devgroup v-for="devgroup in devgroups" v-on:update="onDevgroupClick"></devgroup>
          </div>
        </div>
...
<div class="col-md-8" v-if="selectedDevice.id > 0">
<form class="form-horizontal" v-if="activeTab == 0">
            <div class="form-group">
              <label for="inputImei" class="col-sm-4 control-label">IMEI:</label>
              <div class="col-sm-8">
                <p class="form-control-static">{{selectedDevice.imei}}</p>
              </div>
            </div>
            <div class="form-group">
              <label for="inputName" class="col-sm-4 control-label">Наименование:</label>
              <div class="col-sm-8">
                <input type="text" class="form-control" v-model="selectedDevice.name">
              </div>
            </div>
            <div class="form-group">
              <label for="inputGroup" class="col-sm-4 control-label">Группа:</label>
              <div class="col-sm-8">
                <select class="form-control" v-model="selectedDevice.group_id">
                  <option v-for="devgroup in devgroups" v-bind:value="devgroup.id">{{devgroup.name}}</option>
                </select>
              </div>
            </div>
...
            <div class="form-group">
              <div class="col-md-offset-8 col-md-4 text-right">
                <button type="button" class="btn btn-success" v-bind:class="{disabled: !hasChanges}" v-on:click="saveDevice">Сохранить</button>
              </div>
            </div>
          </form>
</div>
...
</template>

<script>
export default {
    data() {
      return {
        hasChanges: false,
        selectedDevice: {
          id: 0,
          name: '',
          sensors: []
        },
...
      }
    },

    methods: {      
      onDevgroupClick(item) {
        // Clone device object(for editing)
        this.selectedDevice = Object.assign({}, item);
        this.hasChanges = false;
      },
...
    },

    watch : {
      selectedDevice: function() {
        this.hasChanges = true;
      }
    },
...
  }
</script>


Если в двух словах:
Слева список устройств, справа форма редактирования устройства. При клике на элемент списка клонируется объект устройства из списка в объект selectedDevice и сбрасывается флаг hasChanges, который привязан к классу disabled у кнопки "Сохранить". При любом изменении selectedDevice через watch флаг устанавливается в true и кнопка активируется.
Но получается, что кнопка активна всегда. Видимо watch срабатывает после функции клика. По идее задача вполне тривиальна (активировать кнопку при внесении изменений), как Вы ее решали?
  • Вопрос задан
  • 1771 просмотр
Решения вопроса 1
kulakoff
@kulakoff Куратор тега Vue.js
Vue.js developing
Попробуйте обернуть в nextTick, но не уверен, что поможет:
this.$nextTick(function () {
        this.hasChanges = false;
      })

Если это поможет, то позже появится проблема в том, что вы следите за объектом, а точнее за его ссылкой, но она не изменяется пока вы редактируете поля этого объекта.

Попробуйте такой вариант, уберите watch из опций, а выборе устройства (возможны ошибки в синтаксисе):
...
methods: {
  onDevgroupClick(item) {
        // Clone device object(for editing)
        this.selectedDevice = Object.assign({}, item);
        this.hasChanges = false;
        this.$nextTick(() => {
          this.$watch('selectedDevice', this.hasChanged, { deep: true })
        })
      },
  hasChanged() {
    this.hasChanges = true;
  }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
planc
@planc
<form @keydown="hasChanged=true">
<input type="text"/>


</form>
<button class="btn btn-primary" :class="{disabled: !hasChanged}" 
        @click="hasChanged=false">
Click
</button>


https://jsfiddle.net/74jzdwba/3/
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы