Подтвердить что ты не робот

Vue JS Просмотр глубоко вложенного объекта

Отказ от ответственности:. Это моя первая попытка создания MVVM-приложения. Я также не работал с vue.js раньше, поэтому вполне может быть, что моя проблема является результатом более фундаментальной проблемы.


На мой взгляд, у меня есть два типа блоков с флажками:

  • Тип 1: блок/флажки
  • Тип 2: блок/заголовки/флажки

Основной объект структурирован следующим образом:

{
  "someTopLevelSetting": "someValue",
  "blocks": [
    {
      "name": "someBlockName",
      "categryLevel": "false",
      "variables": [
        {
          "name": "someVarName",
          "value": "someVarValue",
          "selected": false,
          "disabled": false
        }
      ]
    },
    {
      "name": "someOtherBlockName",
      "categryLevel": "true",
      "variables": [
        {
          "name": "someVarName",
          "value": "someVarValue",
          "categories": [
            {
              "name": "SomeCatName",
              "value": "someCatValue",
              "selected": false,
              "disabled": false
            }
          ]
        }
      ]
    }
  ]
}

Мои цели

Выбор флажков:

  • Пользователь нажимает на флажок, установлен флажок (selected = true)
  • Устанавливается метод, чтобы проверить, нужно ли отключать любые другие флажки (disabled = true). (Если этот метод действительно отключил что-либо, он также снова вызывает себя, потому что другие элементы могут быть в свою очередь зависимы от отключенного элемента)
  • Другой метод обновляет некоторые другие функции, такие как значки и т.д.

Удаление флажков

Пользователь может нажать кнопку "Очистить", которая отменяет все флажки в списке (selected = false). Это действие также должно инициировать методы, которые необязательно отключают значки и значки обновлений и т.д.

Мой текущий метод (что кажется не совсем правильным)

  • Выбранный атрибут модели данных привязан к проверенному состояние элемента флажка с помощью директивы v-model.
  • Отключенный атрибут (из модели) привязан к классу элемента и отключенному атрибуту. Это состояние задается вышеупомянутым методом.
  • Чтобы инициализировать методы, которые отключают флажки и меняют некоторые значки, я использую директиву v-on="change: checkboxChange(this)". Я думаю, мне нужно сделать эту часть по-другому.
  • Метод clearList вызывается через v-on="click: clearList(this)"

Проблемы с моей текущей настройкой состоят в том, что событие изменения не срабатывает, когда флажки очищаются программно (т.е. не взаимодействием с пользователем).

Вместо этого я хотел бы
Для меня наиболее логичным было бы использовать this.$watch и отслеживать изменения в модели, вместо того, чтобы слушать события DOM.

Как только произойдет изменение, мне нужно будет определить, какой именно элемент изменился, и действовать по этому поводу. Я попытался создать функцию $watch, которая наблюдает массив blocks. Это, похоже, отлично подходит для изменений, но возвращает полный объект, в отличие от индивидуального атрибута, который изменился. Также этот объект не имеет некоторых удобных вспомогательных атрибутов, например $parent.

Я могу думать о некоторых хакерских способах заставить приложение работать (например, вручную изменять события изменения в моем методе clearList и т.д.), но мой пример использования кажется довольно стандартным, поэтому я ожидаю, что, вероятно, будет гораздо более элегантный способ обработки это.

4b9b3361

Ответ 1

Вы можете использовать метод "смотреть", например, если ваши данные:

data: {
    block: {
        checkbox: {
            active:false
        },
        someotherprop: {
            changeme: 0
        }
    }
}

Вы можете сделать что-то вроде этого:

data: {...},
watch: {
   'block.checkbox.active': function() {
        // checkbox active state has changed
        this.block.someotherprop.changeme = 5;
    } 
}

Ответ 2

Так как никто не ответил, и я решил/работал вокруг этого вопроса, я подумал, что это полезно для публикации моего решения. Обратите внимание, что я не уверен, что мое решение заключается в том, как эти типы вещей следует решать, но это работает.

Вместо использования этого прослушивателя событий v-on="change: checkboxChange(this)" Теперь я использую настраиваемую директиву, которая прослушивает как выбранный, так и отключенный атрибут модели, например: v-on-filter-change="selected, disabled".

Директива выглядит так:

directives: {
    'on-filter-change': function(newVal, oldVal) {
        // When the input elements are first rendered, the on-filter-change directive is called as well, 
        // but I only want stuff to happen when a user does someting, so I return when there is no valid old value
        if (typeof oldVal === 'undefined') {
            return false;
        }
        // Do stuff here
        // this.vm is a handy attribute that contains some vue instance information as well as the current object
        // this.expression is another useful attribute with which you can assess which event has taken place
    }
},

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

Возможно, это будет полезно кому-то в будущем.

Ответ 3

Если вы хотите наблюдать за объектом в целом со всеми его свойствами, а не только с одним свойством, вы можете сделать это вместо:

 data() {
    return {
       object: {
          prop1: "a",
          prop2: "b",
       }    
    }
 },
 watch: {
    object: {
        handler(newVal, oldVal) {
            // do something with the object
        },
        deep: true,
    },
},

уведомление handler и deep: true

Ответ 4

Другое решение, не упомянутое здесь: Используйте параметр deep.

watch:{
  block: {
    handler: function () {console.log("changed") },
    deep: true
  }
}