admin管理员组

文章数量:1401673

I'm trying to init an empty array in the data and then get a JSON from the server and populate it.

The problem is that the array always have an extra Observer object so when i log it i see this:

empty items array: [ob: Observer]

here is a code excerpt:

data() {
        return {
            items: []
        }
    },
 created() {
         this.$http.get('/api/menus').then(function (response) {

            console.log('items before', this.items); //THIS LOGS items before: [__ob__: Observer]
             this.items = [].concat(response.body);
            this.items.forEach(function (item) {
              console.log('item', item);

              item.$add('active', false);

              item.tests.forEach(function (test) {
                  test.$add('active', false);
              });
        });

         }).catch(function (err) {
             console.error('err', err);

         });

     },

The problem is that when trying to add a new property to the objects in the array i get an error:

err TypeError: item.$add is not a function

when i debug i see it happens because it considers the observer object as part of the array.

Is it normal? should i just check if $add exists? what about when rendering it in the view, does Vue ignore this object?

I'm trying to init an empty array in the data and then get a JSON from the server and populate it.

The problem is that the array always have an extra Observer object so when i log it i see this:

empty items array: [ob: Observer]

here is a code excerpt:

data() {
        return {
            items: []
        }
    },
 created() {
         this.$http.get('/api/menus').then(function (response) {

            console.log('items before', this.items); //THIS LOGS items before: [__ob__: Observer]
             this.items = [].concat(response.body);
            this.items.forEach(function (item) {
              console.log('item', item);

              item.$add('active', false);

              item.tests.forEach(function (test) {
                  test.$add('active', false);
              });
        });

         }).catch(function (err) {
             console.error('err', err);

         });

     },

The problem is that when trying to add a new property to the objects in the array i get an error:

err TypeError: item.$add is not a function

when i debug i see it happens because it considers the observer object as part of the array.

Is it normal? should i just check if $add exists? what about when rendering it in the view, does Vue ignore this object?

Share Improve this question edited Mar 24, 2017 at 10:06 Tomer asked Mar 24, 2017 at 9:03 TomerTomer 17.9k16 gold badges81 silver badges139 bronze badges 8
  • I think this is normal, because VueJS use observers for reactivity, so each item in data object has attached observer.Check this but with Browser Console, not using the JsBin jsbin./qusugoyame/edit?html,js,console,output – Belmin Bedak Commented Mar 24, 2017 at 9:44
  • Yes, all correct, and what is the problem though? – euvl Commented Mar 24, 2017 at 9:54
  • What should be $add method ? It depracated use $set – Belmin Bedak Commented Mar 24, 2017 at 10:17
  • 1 Here is the working example jsbin./qusugoyame/edit?html,js,console,output - let me know are you looking for this so I can explain it and add as answer – Belmin Bedak Commented Mar 24, 2017 at 10:51
  • 1 Yeah using arrow function sometimes could solve context issue depending on situation.@GONG provided good answer so you can accept it, there are no need to post mine one. – Belmin Bedak Commented Mar 24, 2017 at 11:07
 |  Show 3 more ments

1 Answer 1

Reset to default 5

According to your code, you want to set active property in your items object to false. Also you want to set all the properties active in every item's tests property to false.

Vue.js is reactive and detect changes automatically, but only for objects themselves, not their properties. For array vue will only detect changes by those methods (more about list rendering in vue.js https://v2.vuejs/v2/guide/list.html#ad):

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

But how about properties? You can force vue to see change in deep of array or object with Vue.set(object, property, value) or this.$set in any Vue instance.

So, in your example you can implement it like this:

this.items.forEach(function (item, key) {
    console.log('item', item);

    this.$set(this.items[key], 'active', false);

    item.tests.forEach(function (test, testKey) {
        this.$set(this.items[key].tests[testKey], 'active', false);
    }, this);
}, this);

And it should work. Here is working example: http://jsbin./cegafiqeyi/edit?html,js,output (some ES6 features used, don't be confused)

本文标签: javascriptVue empty array automatically populated with Observer objectStack Overflow