brahim siempay brahim siempay - 1 month ago 10
Javascript Question

is there a way to watch inputs (v-model) in a v-for loop

I have an Array of objects that I loop through, and I wana watch an input related to each object, but the problem is the v-model="something" : this something changes so I dont know what to watch

<table class="table displaynone" id="table-sauces" >
<tr v-for="o in order">
<td>@{{o.produit}} @{{o.num}}</td>
<td v-for="sauce in les_sauce">
<input type="radio" :name="o.produit+o.num"
@click="$emit(setsauce(o.is_menu))"
:value="sauce.id" v-model="o.sauce"> @{{sauce.name}}
<img :src="sauce.link">
</td>
</tr>
</table>


How can I watch the value of that input ?

Answer

You are having two levels of loop, and they seem to loop on different things (order and les_sauce).

Nevertheless, here is a simplified example that uses the inner loop of your code (v-for="sauce in les_sauce") and shows how you can watch for changes:

You can create a separate child component for each of those array items and watch for changes inside the child component.

For example, this is the looping part in parent component template:

<td v-for="sauce in les_sauce">
    <sauce-view :sauce="sauce" :ord="o"></sauce-view>
</td>

and your child component:

Vue.component('sauce-view', {
    props: ["sauce", "ord"],
    template: `
        <div class="sauce-view">
            <input type="radio" :name="ord.produit+ord.num"
            @click="$emit(setsauce(ord.is_menu))"
            :value="sauce.id" v-model="ord.sauce">  @{{sauce.name}}
            <img :src="sauce.link">
        </div>`,
    watch: {
        sauce: function() {
            // this will get triggered within sauce-view component, when one of your "sauce" changes
        },
        ord: function() {
            // this will get triggered within sauce-view component, when one of your "o" changes
        }
    }
})

As shown in the sample code for child component code above, here you can watch for individual array items from parent - o and sauce

Note: o in parent gets passed as ord to the child component. This is an example to show how the variables need not be the same in parent and child components.

EDIT: additional information after comment #4 (deep watching)

In my sample code above, I did not set deep:true which is needed for watching deep.

Here are the relevant lines from the API document:

Option: deep

To also detect nested value changes inside Objects, you need to pass in deep: true in the options argument.

In your case, you can modify the sample code above as follows:

watch: {
    sauce: {
        handler: function() {
            // this will get triggered when any of the nested values of "sauce" change
        },
        deep: true  // this enables watching the nested values inside this object 
    },
    ord: function() {
        // this will get triggered within sauce-view component, when one of your "o" changes
    }
}

Hope it helps!