How to update a v-for variable in Vue JS?

Asked

Viewed 1,022 times

1

I have the following code in my view:

<div>
    <div v-for="(solicitacao, $index) in solicitacoes">

        <div class="box-image" :class="{'box-rejected' : solicitacao.$$reprovado}">

            <div class="box-image-header">
                @{{ solicitacao.usuario.nome }}
            </div>

            <div class="box-image-body">
                <img :src="solicitacao.foto_link" src="https://placehold.it/300x400">
            </div>

            <div class="box-image-footer">

                <button class='wgm-btn wgm-btn-red' type="button" v-on:click="reprovar(solicitacao, $index)">
                    Reprovar
                </button>
                <button class='wgm-btn wgm-btn-blue' type="button" v-on:click="aprovar(solicitacao)">
                    Aprovar
                </button>
            </div>

            <div class="box-image-overlay"></div>
        </div>
    </div>
</div>

I get the variable solicitacoes through an Ajax

new Vue({
    el: '#vue-gerenciar-fotos',
    data: {
        carregando: true,
        ficha_tecnica_id: undefined,
        solicitacoes: []

    },

    mounted: function () {

        this.ficha_tecnica_id = $(this.$el).data('fichaTecnicaId');

        this.carregarSolicitacoes(1);
    },

    methods: {

        carregarSolicitacoes: function (page) {

            var that;

            that = this;

            that.carregando = true;

            $.get('/solicitacao/ajax-aguardando-aprovacao-foto/' + this.ficha_tecnica_id, {page: page}, function (response) {

                Array.prototype.push.apply(that.solicitacoes, response.solicitacoes);

                that.carregando = false;

                if (page != response.last_page) {
                    that.carregarSolicitacoes(++page);
                }
            });
        },

        reprovar: function (solicitacao, $index) {

            solicitacao.$$reprovado = true;

        },

        aprovar: function (solicitacao) {

            solicitacao.$$aprovado = true;
        }
    },
});

When I click the "Fail" button, the function reprovar is called (I even ran tests on the Console). However, even setting the value solicitacao.$$reprovado as true, nothing happens in View.

You should modify the class to box-reject once I clicked the button, since the value $$reprovado was added.

Why is the View value not being updated? In Angular this would work smoothly.

What is needed to work adding a new value to the object solicitacao who is in the v-for?

  • The key $$reprovado exists in all items arriving from ajax?

  • @bfavaretto no, she is created after.

2 answers

1

In Vue, if you dynamically insert a property into a reactive object, she will not be reactive:

window.onload = function() {
  var vm = new Vue({
    el: '#app',
    data: { 
      inventory: [
        // Só o 1o item tem a propriedade 'test'
        {name: 'MacBook Air', price: 1000, test: ''}, 
        {name: 'MacBook Pro', price: 1800},
        {name: 'Lenovo W530', price: 1400},
        {name: 'Acer Aspire One', price: 300}
      ]
    },

    methods: {
      clicked(item) {
        item.test = "clicked";
      },
    }
  });
};
<script src="https://unpkg.com/[email protected]"></script>

<p>Clique nos itens abaixo:</p>

<div id="app">
  <ul>
    <li v-for="item in inventory" @click="clicked(item)">
      {{ item.name }} - {{ item.test }}
    </li>
  </ul>
</div>

To solve, you need to use the Vue.set:

window.onload = function() {
  var vm = new Vue({
    el: '#app',
    data: { 
      inventory: [
        // Só o 1o item tem a propriedade 'test'
        {name: 'MacBook Air', price: 1000, test: ''}, 
        {name: 'MacBook Pro', price: 1800},
        {name: 'Lenovo W530', price: 1400},
        {name: 'Acer Aspire One', price: 300}
      ]
    },

    methods: {
      clicked(item) {
        this.$set(item, 'test', 'clicked');
      },
    }
  });
};
<script src="https://unpkg.com/[email protected]"></script>

<p>Clique nos itens abaixo:</p>

<div id="app">
  <ul>
    <li v-for="item in inventory" @click="clicked(item)">
      {{ item.name }} - {{ item.test }}
    </li>
  </ul>
</div>

0

Browser other questions tagged

You are not signed in. Login or sign up in order to post.