How to do two way binding

Good day jwj001,
I created a template node for a separated button. It should be a combo button including a v-btn for changing the page and activating dynamic content. The other component is a switch for smart-home control. The goal is to be able to control the power state of a specific lamp without entering the settings page of the device. The data is provided by iobroker.

<div class="so-bs-grid-container">
    <v-btn class="so-bs-button" @click="send({payload: provideData(value) })">
        Testgerät
    </v-btn>
    <v-switch class="so-bs-switch" v-model="msg.payload"
        active-color="primary"
        color="primary"
        inset 
        @update:modelValue="send({payload: provideSwitchData(msg.payload) })">
    </v-switch>
</div>

<script>
    export default {
        data() {
            // define variables available component-wide
            // (in <template> and component functions)            
            return {
                topic: "alias.0.devices.lights.CompLgt-OG-AZ.General",
            }
        },
        methods: {
            provideData: function () {
                var message = {
                    scope: "button",
                    title: "< OG: Beleuchtung",
                    page: "lightcontrol.rgb",
                    topic: this.topic,
                };
                return message;
            },
            provideSwitchData: function (switchValue) {
                var message = {
                    scope: "switch",
                    topic: this.topic + ".Control.ONOFF",
                    value: switchValue,
                };
                return message;
            },
        },
    }
</script>

Now the problem is that I can inject the message payload, but if I create a dynamic v-model using the msg.payload, I am not able to define a standard value for it in the data section.
If I try to create a property binding, the application crashes.
How can I define a two-way binding according to a message input and make sure that the latest value of the switch persists, even if I send a message due to a click on the button in the same widget?

@nr_luna_mw I moved your question to its own thread (as far as i could tell, it was a new question and unrelated to the original question)

Does anyone have a solution regarding to this problem?

If I'm understanding correctly, you can use a variable called value, then watch () on msg.payload for changes. When that changes, update value.

<div class="so-bs-grid-container">
    <v-btn class="so-bs-button" @click="send({payload: provideData(value) })">
        Testgerät
    </v-btn>
    <v-switch class="so-bs-switch" v-model="value"
        active-color="primary"
        color="primary"
        inset 
        @update:modelValue="send({payload: provideSwitchData(msg.payload) })">
    </v-switch>
</div>

<script>
    export default {
        data() {
            // define variables available component-wide
            // (in <template> and component functions)            
            return {
                value: null,
                topic: "alias.0.devices.lights.CompLgt-OG-AZ.General",
            }
        },
        watch: {
            'msg.payload': function (payload) {
                 this.value = payload
            }
        },
        methods: {
            provideData: function () {
                var message = {
                    scope: "button",
                    title: "< OG: Beleuchtung",
                    page: "lightcontrol.rgb",
                    topic: this.topic,
                };
                return message;
            },
            provideSwitchData: function (switchValue) {
                var message = {
                    scope: "switch",
                    topic: this.topic + ".Control.ONOFF",
                    value: switchValue,
                };
                return message;
            },
        },
    }
</script>

I haven't tested this, but that should do the trick

Hello joepavitt, thank you,
unfortunately it does not work yet, because obviously
the scope.$watch('msg.payload', function(data) way
seems not to be the same like the wrapper function "watch:" in the vue.js context.

I also tried to only watch the whole msg object, but it does not seem to work.
Using the scope.$watch will cause that the switch is able to react to the incoming message value, but then I am unable to control the switch manually. It won´t send any message, if I click on it.

<template>
    <div>Template Content Here</div>
</template>

<script>
    export default {
        watch: {
            msg: function () {
                console.log('input has arrived', this.msg)
            }
        }
    }
</script>

Here is a working example, tested locally. Needed to watch the full msg object, rather than just the msg.payload

Yes, perfect. This solved the problem.
Thanks a lot.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.