Vuejs bind custom event on nested component within for loop












1















I'm using three single-file-components.





  • ParentVariation.vue

  • VariationInfo.vue

  • Childvariation.vue


I'm emitting MarkedFilled event from child component variation-info, and catching that event on ParentVariation. Here's the content of ParentVariation.vue :



<template>
<section class="parentVariation">
<label :for="'key-'+row.id">Key</label>

<select :name="'key-'+row.id" :id="'key-'+row.id" class="select2"></select>

<label :for="'value-'+row.id">Value</label>
<input :name="'value-'+row.id" :id="'value-'+row.id">

<label :for="'quantity-'+row.id">quantity</label>
<input :name="'quantity-'+row.id" :id="'quantity-'+row.id">

<variation-info :filled="row.filled" @markedFilled="row.filled='true'" :key="row.id"></variation-info>

<button @click="addChild" type="button" class="btn btn-link btn-sm btn-fw">
<i class="mdi mdi-table-column-plus-after"></i>
Add Child
</button>

<button @click="popChild" type="button" class="btn btn-link text-danger btn-sm btn-fw">
<i class="mdi mdi-table-column-remove"></i>
Drop Child
</button>

<br>

<div v-if="row.child.length > 0">
<child-variation v-for="child in row.child" :childIndex="child.id" :parentIndex="row.id" :key="child.id"></child-variation>
</div>
</section>
</template>

<script>
export default {

props: [ 'row' ],

methods: {

addChild() {
this.row.child.push({ id:this.row.child.length, filled:'' })
},

popChild() {
this.row.child.pop()
},

}

}
</script>


On the Main Vue-Instance. i have this:



data: function() {
return {
parents: [{ id:0, child: , filled:'' }]
}
},


And I've initialized ParentVariation like so:



<parent-variation v-for="parent in parents" :row="parent" :key="parent.id"></parent-variation>


i'm trying to achieve this functionality: When MarkedFilled event is called from child component (variation-info). Parent component (parent-variation) will catch that & update filled property for data parent on main vue instance.



But each time this event is called, only first parent element's filled property is changed. I want to change the property of the clicked element.



I've been trying to figure this out for 2 days now, Any help is appreciated.
I just want to understand why only first element is called each time.










share|improve this question

























  • You should change data to function vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

    – ittus
    Nov 20 '18 at 9:34











  • @ittus I'm so sorry about that. I've updated data to a function now.

    – Shreyansh Panchal
    Nov 20 '18 at 9:37











  • If you are trying to change filled property of a specific object you should send that parent's id in the emit than call a function on @markedFilled and then change the filled property according to the id in that function.

    – Haseeb Rehman
    Nov 20 '18 at 9:40











  • forum.vuejs.org/t/passing-data-back-to-parent/1201/2 look for the answer by ktsn it explains how you can pass data on emit and call a function on that emit.

    – Haseeb Rehman
    Nov 20 '18 at 9:46
















1















I'm using three single-file-components.





  • ParentVariation.vue

  • VariationInfo.vue

  • Childvariation.vue


I'm emitting MarkedFilled event from child component variation-info, and catching that event on ParentVariation. Here's the content of ParentVariation.vue :



<template>
<section class="parentVariation">
<label :for="'key-'+row.id">Key</label>

<select :name="'key-'+row.id" :id="'key-'+row.id" class="select2"></select>

<label :for="'value-'+row.id">Value</label>
<input :name="'value-'+row.id" :id="'value-'+row.id">

<label :for="'quantity-'+row.id">quantity</label>
<input :name="'quantity-'+row.id" :id="'quantity-'+row.id">

<variation-info :filled="row.filled" @markedFilled="row.filled='true'" :key="row.id"></variation-info>

<button @click="addChild" type="button" class="btn btn-link btn-sm btn-fw">
<i class="mdi mdi-table-column-plus-after"></i>
Add Child
</button>

<button @click="popChild" type="button" class="btn btn-link text-danger btn-sm btn-fw">
<i class="mdi mdi-table-column-remove"></i>
Drop Child
</button>

<br>

<div v-if="row.child.length > 0">
<child-variation v-for="child in row.child" :childIndex="child.id" :parentIndex="row.id" :key="child.id"></child-variation>
</div>
</section>
</template>

<script>
export default {

props: [ 'row' ],

methods: {

addChild() {
this.row.child.push({ id:this.row.child.length, filled:'' })
},

popChild() {
this.row.child.pop()
},

}

}
</script>


On the Main Vue-Instance. i have this:



data: function() {
return {
parents: [{ id:0, child: , filled:'' }]
}
},


And I've initialized ParentVariation like so:



<parent-variation v-for="parent in parents" :row="parent" :key="parent.id"></parent-variation>


i'm trying to achieve this functionality: When MarkedFilled event is called from child component (variation-info). Parent component (parent-variation) will catch that & update filled property for data parent on main vue instance.



But each time this event is called, only first parent element's filled property is changed. I want to change the property of the clicked element.



I've been trying to figure this out for 2 days now, Any help is appreciated.
I just want to understand why only first element is called each time.










share|improve this question

























  • You should change data to function vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

    – ittus
    Nov 20 '18 at 9:34











  • @ittus I'm so sorry about that. I've updated data to a function now.

    – Shreyansh Panchal
    Nov 20 '18 at 9:37











  • If you are trying to change filled property of a specific object you should send that parent's id in the emit than call a function on @markedFilled and then change the filled property according to the id in that function.

    – Haseeb Rehman
    Nov 20 '18 at 9:40











  • forum.vuejs.org/t/passing-data-back-to-parent/1201/2 look for the answer by ktsn it explains how you can pass data on emit and call a function on that emit.

    – Haseeb Rehman
    Nov 20 '18 at 9:46














1












1








1








I'm using three single-file-components.





  • ParentVariation.vue

  • VariationInfo.vue

  • Childvariation.vue


I'm emitting MarkedFilled event from child component variation-info, and catching that event on ParentVariation. Here's the content of ParentVariation.vue :



<template>
<section class="parentVariation">
<label :for="'key-'+row.id">Key</label>

<select :name="'key-'+row.id" :id="'key-'+row.id" class="select2"></select>

<label :for="'value-'+row.id">Value</label>
<input :name="'value-'+row.id" :id="'value-'+row.id">

<label :for="'quantity-'+row.id">quantity</label>
<input :name="'quantity-'+row.id" :id="'quantity-'+row.id">

<variation-info :filled="row.filled" @markedFilled="row.filled='true'" :key="row.id"></variation-info>

<button @click="addChild" type="button" class="btn btn-link btn-sm btn-fw">
<i class="mdi mdi-table-column-plus-after"></i>
Add Child
</button>

<button @click="popChild" type="button" class="btn btn-link text-danger btn-sm btn-fw">
<i class="mdi mdi-table-column-remove"></i>
Drop Child
</button>

<br>

<div v-if="row.child.length > 0">
<child-variation v-for="child in row.child" :childIndex="child.id" :parentIndex="row.id" :key="child.id"></child-variation>
</div>
</section>
</template>

<script>
export default {

props: [ 'row' ],

methods: {

addChild() {
this.row.child.push({ id:this.row.child.length, filled:'' })
},

popChild() {
this.row.child.pop()
},

}

}
</script>


On the Main Vue-Instance. i have this:



data: function() {
return {
parents: [{ id:0, child: , filled:'' }]
}
},


And I've initialized ParentVariation like so:



<parent-variation v-for="parent in parents" :row="parent" :key="parent.id"></parent-variation>


i'm trying to achieve this functionality: When MarkedFilled event is called from child component (variation-info). Parent component (parent-variation) will catch that & update filled property for data parent on main vue instance.



But each time this event is called, only first parent element's filled property is changed. I want to change the property of the clicked element.



I've been trying to figure this out for 2 days now, Any help is appreciated.
I just want to understand why only first element is called each time.










share|improve this question
















I'm using three single-file-components.





  • ParentVariation.vue

  • VariationInfo.vue

  • Childvariation.vue


I'm emitting MarkedFilled event from child component variation-info, and catching that event on ParentVariation. Here's the content of ParentVariation.vue :



<template>
<section class="parentVariation">
<label :for="'key-'+row.id">Key</label>

<select :name="'key-'+row.id" :id="'key-'+row.id" class="select2"></select>

<label :for="'value-'+row.id">Value</label>
<input :name="'value-'+row.id" :id="'value-'+row.id">

<label :for="'quantity-'+row.id">quantity</label>
<input :name="'quantity-'+row.id" :id="'quantity-'+row.id">

<variation-info :filled="row.filled" @markedFilled="row.filled='true'" :key="row.id"></variation-info>

<button @click="addChild" type="button" class="btn btn-link btn-sm btn-fw">
<i class="mdi mdi-table-column-plus-after"></i>
Add Child
</button>

<button @click="popChild" type="button" class="btn btn-link text-danger btn-sm btn-fw">
<i class="mdi mdi-table-column-remove"></i>
Drop Child
</button>

<br>

<div v-if="row.child.length > 0">
<child-variation v-for="child in row.child" :childIndex="child.id" :parentIndex="row.id" :key="child.id"></child-variation>
</div>
</section>
</template>

<script>
export default {

props: [ 'row' ],

methods: {

addChild() {
this.row.child.push({ id:this.row.child.length, filled:'' })
},

popChild() {
this.row.child.pop()
},

}

}
</script>


On the Main Vue-Instance. i have this:



data: function() {
return {
parents: [{ id:0, child: , filled:'' }]
}
},


And I've initialized ParentVariation like so:



<parent-variation v-for="parent in parents" :row="parent" :key="parent.id"></parent-variation>


i'm trying to achieve this functionality: When MarkedFilled event is called from child component (variation-info). Parent component (parent-variation) will catch that & update filled property for data parent on main vue instance.



But each time this event is called, only first parent element's filled property is changed. I want to change the property of the clicked element.



I've been trying to figure this out for 2 days now, Any help is appreciated.
I just want to understand why only first element is called each time.







javascript vue.js






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 9:40







Shreyansh Panchal

















asked Nov 20 '18 at 9:23









Shreyansh PanchalShreyansh Panchal

7111




7111













  • You should change data to function vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

    – ittus
    Nov 20 '18 at 9:34











  • @ittus I'm so sorry about that. I've updated data to a function now.

    – Shreyansh Panchal
    Nov 20 '18 at 9:37











  • If you are trying to change filled property of a specific object you should send that parent's id in the emit than call a function on @markedFilled and then change the filled property according to the id in that function.

    – Haseeb Rehman
    Nov 20 '18 at 9:40











  • forum.vuejs.org/t/passing-data-back-to-parent/1201/2 look for the answer by ktsn it explains how you can pass data on emit and call a function on that emit.

    – Haseeb Rehman
    Nov 20 '18 at 9:46



















  • You should change data to function vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

    – ittus
    Nov 20 '18 at 9:34











  • @ittus I'm so sorry about that. I've updated data to a function now.

    – Shreyansh Panchal
    Nov 20 '18 at 9:37











  • If you are trying to change filled property of a specific object you should send that parent's id in the emit than call a function on @markedFilled and then change the filled property according to the id in that function.

    – Haseeb Rehman
    Nov 20 '18 at 9:40











  • forum.vuejs.org/t/passing-data-back-to-parent/1201/2 look for the answer by ktsn it explains how you can pass data on emit and call a function on that emit.

    – Haseeb Rehman
    Nov 20 '18 at 9:46

















You should change data to function vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

– ittus
Nov 20 '18 at 9:34





You should change data to function vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

– ittus
Nov 20 '18 at 9:34













@ittus I'm so sorry about that. I've updated data to a function now.

– Shreyansh Panchal
Nov 20 '18 at 9:37





@ittus I'm so sorry about that. I've updated data to a function now.

– Shreyansh Panchal
Nov 20 '18 at 9:37













If you are trying to change filled property of a specific object you should send that parent's id in the emit than call a function on @markedFilled and then change the filled property according to the id in that function.

– Haseeb Rehman
Nov 20 '18 at 9:40





If you are trying to change filled property of a specific object you should send that parent's id in the emit than call a function on @markedFilled and then change the filled property according to the id in that function.

– Haseeb Rehman
Nov 20 '18 at 9:40













forum.vuejs.org/t/passing-data-back-to-parent/1201/2 look for the answer by ktsn it explains how you can pass data on emit and call a function on that emit.

– Haseeb Rehman
Nov 20 '18 at 9:46





forum.vuejs.org/t/passing-data-back-to-parent/1201/2 look for the answer by ktsn it explains how you can pass data on emit and call a function on that emit.

– Haseeb Rehman
Nov 20 '18 at 9:46












1 Answer
1






active

oldest

votes


















0














You might want to try emitting markedFilled event to parent component:



In ParentVariation.vue



<variation-info :filled="row.filled" @markedFilled="$emit('markedFilled')" :key="row.id">
</variation-info>


and in main



<parent-variation v-for="(parent, index) in parents" :row="parent" :key="parent.id" @markedFilled="changeFilled(index)">
</parent-variation>

export default {
data: function() {
return {
parents: [{ id:0, child: , filled:'' }]
}
},
methods: {
changeFilled(index) {
this.parents[index].filled = true
this.parents = JSON.parse(JSON.stringify(this.parents))
}
}
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53389804%2fvuejs-bind-custom-event-on-nested-component-within-for-loop%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You might want to try emitting markedFilled event to parent component:



    In ParentVariation.vue



    <variation-info :filled="row.filled" @markedFilled="$emit('markedFilled')" :key="row.id">
    </variation-info>


    and in main



    <parent-variation v-for="(parent, index) in parents" :row="parent" :key="parent.id" @markedFilled="changeFilled(index)">
    </parent-variation>

    export default {
    data: function() {
    return {
    parents: [{ id:0, child: , filled:'' }]
    }
    },
    methods: {
    changeFilled(index) {
    this.parents[index].filled = true
    this.parents = JSON.parse(JSON.stringify(this.parents))
    }
    }
    }





    share|improve this answer




























      0














      You might want to try emitting markedFilled event to parent component:



      In ParentVariation.vue



      <variation-info :filled="row.filled" @markedFilled="$emit('markedFilled')" :key="row.id">
      </variation-info>


      and in main



      <parent-variation v-for="(parent, index) in parents" :row="parent" :key="parent.id" @markedFilled="changeFilled(index)">
      </parent-variation>

      export default {
      data: function() {
      return {
      parents: [{ id:0, child: , filled:'' }]
      }
      },
      methods: {
      changeFilled(index) {
      this.parents[index].filled = true
      this.parents = JSON.parse(JSON.stringify(this.parents))
      }
      }
      }





      share|improve this answer


























        0












        0








        0







        You might want to try emitting markedFilled event to parent component:



        In ParentVariation.vue



        <variation-info :filled="row.filled" @markedFilled="$emit('markedFilled')" :key="row.id">
        </variation-info>


        and in main



        <parent-variation v-for="(parent, index) in parents" :row="parent" :key="parent.id" @markedFilled="changeFilled(index)">
        </parent-variation>

        export default {
        data: function() {
        return {
        parents: [{ id:0, child: , filled:'' }]
        }
        },
        methods: {
        changeFilled(index) {
        this.parents[index].filled = true
        this.parents = JSON.parse(JSON.stringify(this.parents))
        }
        }
        }





        share|improve this answer













        You might want to try emitting markedFilled event to parent component:



        In ParentVariation.vue



        <variation-info :filled="row.filled" @markedFilled="$emit('markedFilled')" :key="row.id">
        </variation-info>


        and in main



        <parent-variation v-for="(parent, index) in parents" :row="parent" :key="parent.id" @markedFilled="changeFilled(index)">
        </parent-variation>

        export default {
        data: function() {
        return {
        parents: [{ id:0, child: , filled:'' }]
        }
        },
        methods: {
        changeFilled(index) {
        this.parents[index].filled = true
        this.parents = JSON.parse(JSON.stringify(this.parents))
        }
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 9:58









        ittusittus

        6,1522723




        6,1522723






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53389804%2fvuejs-bind-custom-event-on-nested-component-within-for-loop%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

            A Topological Invariant for $pi_3(U(n))$