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 и т.д.), но мой пример использования кажется довольно стандартным, поэтому я ожидаю, что, вероятно, будет гораздо более элегантный способ обработки это.
Ответы
Ответ 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
}
}