Vue JS观看深层嵌套对象

时间:2015-05-08 13:00:03

标签: javascript mvvm 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
            }
          ]
        }
      ]
    }
  ]
}

我的目标

选择复选框:

  1. 用户点击复选框,选中复选框(选中= true)
  2. 触发方法以检查是否需要禁用任何其他复选框(disabled = true)。 (如果此方法确实已禁用任何内容,它也会再次调用自身,因为其他项可能依赖于已禁用的项目)
  3. 另一种方法更新了其他一些东西,比如图标等
  4. 清除复选框

    用户可以单击“清除”按钮,该按钮取消选中列表中的所有复选框(选中= false)。此操作还应触发可选地禁用复选框和更新图标等的方法。

    我当前的方法 (这似乎不太正确)

    • 数据模型的选定属性绑定到选中的 通过v-model指令的checkbox元素的状态。
    • disabled属性(来自模型)绑定到元素的class和disabled属性。该状态由上述方法设定。
    • 要初始化禁用复选框和更改某些图标的方法,我使用的是v-on="change: checkboxChange(this)"指令。 我认为我需要以不同方式完成此部分
    • clearList方法通过v-on="click: clearList(this)"
    • 调用

    我当前设置的问题是,当以编程方式清除复选框时(即不是通过用户交互),更改事件不会触发。

    我想要的是
    对我来说,最合乎逻辑的做法是使用this.$watch并跟踪模型中的更改,而不是侦听DOM事件。

    一旦发生变化,我就需要确定哪个确切的项目已更改,并采取相应措施。我试图创建一个观察$watch数组的blocks函数。这似乎可以很好地了解变化,但它返回的是完整对象,而不是已更改的单个属性。此对象也缺少一些方便的帮助器属性,如$parent

    我可以想到一些使应用程序工作的hacky方法(比如在我的clearList方法中手动触发更改事件等)但我的用例似乎非常标准,所以我希望有一种更优雅的方式来处理此

4 个答案:

答案 0 :(得分:68)

您可以使用'watch'方法..例如,如果您的数据是:

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

你可以这样做:

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

答案 1 :(得分:17)

如果你想要整个对象及其所有属性,而不仅仅是一个属性,你可以这样做:

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

请注意handlerdeep: true

答案 2 :(得分:7)

由于没有人回复,我现在已经解决/解决了这个问题,我认为migth对于发布我的解决方案很有用。请注意,我不确定我的解决方案是如何处理这些类型的事情,但它确实有用。

我现在使用一个自定义指令,而不是使用此事件侦听器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子句看起来有点hacky,但我找不到另一种方法。至少这一切都有效。

也许这对未来的某个人有用。

答案 3 :(得分:5)

此处未提及的其他解决方案: 使用deep选项。

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