3

I'm displaying a list of objects with VueJS like so:

<div v-for="register in registers">
    <input type="checkbox" v-model="register.isEnabled">
    <input type="text" v-model="register.name" :disabled="!register.isEnabled">

    <span v-if="register.saved">Saved</span>
    <span v-else><a @click="save(register)">Save now</a></span>
</div>

What I'd like to do, is to watch for changes in this object's values and set the saved attribute to false. This is an exemplary version of my Vue instance:

new Vue({
    el: '#app',
    data: {
        registers: [
            { isEnabled: true, name: 'Register 1', saved: true },
            { isEnabled: false, name: '', saved: true },
        ]
    },
    methods: {
        save: function(event) {
            // Save object, set saved to true
        }
    }
});

I've tried settings an onchange listener to the div with the v-for attribute:

<div v-for="register in registers" @change="onChange(register)">

However this only triggers when the first input element is changed (e.g. the checkbox).

Am I able to somehow listen to all changes made to this register object, without having to add a @change event to every single input? If so, how?

1 Answer 1

1

Am I able to somehow listen to all changes made to this register object, without having to add a @change event to every single input?

This sounds like a pretty reasonable solution actually, especially since the change event doesn't bubble.

I tried to come up with a solution using watch, but since deep watch is not an option for large arrays, it would become pretty messy.

new Vue({
    el: '#app',
    ready: function() {
        this.registers.forEach(function(register, index) {
            this.$watch('registers[' + index + ']', function(newRegister, oldRegister) {
              // Check that it wasn't the `saved` state that changed
              if (newRegister.saved === oldRegister.saved) {
                  newRegister.saved = false;
              }
            });
        });
    },
    data: {
        registers: [
            { isEnabled: true, name: 'Register 1', saved: true },
            { isEnabled: false, name: '', saved: true },
        ]
    },
    methods: {
        save: function(event) {
            // Save object, set saved to true
        }
    }
});

And then you would have to rebind all the watchers in case the registers properties change.

So you're probably easier off just using @change listeners.

Sign up to request clarification or add additional context in comments.

2 Comments

Agree with nils generally ... run a loop on the properties of each item you want to watch in the array ... although nils I think it's this.$watch to setup the listener, not this.watch ;)
Thanks, corrected that ;) I'm not voting for my solution though, I'm much for the OP's solution :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.