Vue: Forcing child component to react to changes in its prop (which is a dictionary)
up vote
1
down vote
favorite
I am currently generating a table which lists problems encountered during the selected test using a component generated with this code:
<tr is="entry" v-for="problem in problems" :key="problem.id" v-bind:foo="problem"></tr>
Each problem corresponds to an item whose relevant information is contained within the problem dictionary and referenced in the first few columns of the table. Since the same item can have multiple problems, the same item can appear in multiple rows of the table. Now, each row features some buttons which allow you to modify the underlying item so as to fix the problems.
Whenever I modify one of those underlying items I need to modify it in all the rows, which i do by calling a function in the parent component, but modifying the data inside of the dictionary does not seem to trigger any of my watches or computes inside of the child component, which currently looks something like this:
Vue.component('entry', {
props: ['foo'],
data: function(){
//does some computations
return data
},
watch:{
foo: function(){
this.recompute_entry()
},
},
methods:{
//various methods, including:
recompute_entry: function(){
//updates the data according to changes brought to the entry
},
},
});
I have attempted to include a different prop which i could bind to an entry in a list in my parent component but, besides being pretty clunky, that didn't end up working either, which makes me think I might've gotten something wrong with my component.
Ultimately, I have relied on the fact that v-for iterates through my list in an orderly fashion, which combined with the fact that I generate no other children in my parent component means that a child component would have the same index in my component's children array as it would in my problems array. Therefore I can use this:
this.$children[problem_index].recompute_entry();
Which kind of feels hack-ish and unreliable, but actually works, for once. Is there no alternative safer method to recalculate my child components based on changes made to their props? I really feel there has to be.
vue.js vue-component parent-child vue-reactivity
add a comment |
up vote
1
down vote
favorite
I am currently generating a table which lists problems encountered during the selected test using a component generated with this code:
<tr is="entry" v-for="problem in problems" :key="problem.id" v-bind:foo="problem"></tr>
Each problem corresponds to an item whose relevant information is contained within the problem dictionary and referenced in the first few columns of the table. Since the same item can have multiple problems, the same item can appear in multiple rows of the table. Now, each row features some buttons which allow you to modify the underlying item so as to fix the problems.
Whenever I modify one of those underlying items I need to modify it in all the rows, which i do by calling a function in the parent component, but modifying the data inside of the dictionary does not seem to trigger any of my watches or computes inside of the child component, which currently looks something like this:
Vue.component('entry', {
props: ['foo'],
data: function(){
//does some computations
return data
},
watch:{
foo: function(){
this.recompute_entry()
},
},
methods:{
//various methods, including:
recompute_entry: function(){
//updates the data according to changes brought to the entry
},
},
});
I have attempted to include a different prop which i could bind to an entry in a list in my parent component but, besides being pretty clunky, that didn't end up working either, which makes me think I might've gotten something wrong with my component.
Ultimately, I have relied on the fact that v-for iterates through my list in an orderly fashion, which combined with the fact that I generate no other children in my parent component means that a child component would have the same index in my component's children array as it would in my problems array. Therefore I can use this:
this.$children[problem_index].recompute_entry();
Which kind of feels hack-ish and unreliable, but actually works, for once. Is there no alternative safer method to recalculate my child components based on changes made to their props? I really feel there has to be.
vue.js vue-component parent-child vue-reactivity
2
Consider using [vuex|vuex.vuejs.org/] to store your data as your application's "state" and define mutations/getters to modify/access it. they have very nice examples in their github such as github.com/vuejs/vuex/tree/dev/examples/shopping-cart
– mmbrian
Nov 22 at 16:23
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am currently generating a table which lists problems encountered during the selected test using a component generated with this code:
<tr is="entry" v-for="problem in problems" :key="problem.id" v-bind:foo="problem"></tr>
Each problem corresponds to an item whose relevant information is contained within the problem dictionary and referenced in the first few columns of the table. Since the same item can have multiple problems, the same item can appear in multiple rows of the table. Now, each row features some buttons which allow you to modify the underlying item so as to fix the problems.
Whenever I modify one of those underlying items I need to modify it in all the rows, which i do by calling a function in the parent component, but modifying the data inside of the dictionary does not seem to trigger any of my watches or computes inside of the child component, which currently looks something like this:
Vue.component('entry', {
props: ['foo'],
data: function(){
//does some computations
return data
},
watch:{
foo: function(){
this.recompute_entry()
},
},
methods:{
//various methods, including:
recompute_entry: function(){
//updates the data according to changes brought to the entry
},
},
});
I have attempted to include a different prop which i could bind to an entry in a list in my parent component but, besides being pretty clunky, that didn't end up working either, which makes me think I might've gotten something wrong with my component.
Ultimately, I have relied on the fact that v-for iterates through my list in an orderly fashion, which combined with the fact that I generate no other children in my parent component means that a child component would have the same index in my component's children array as it would in my problems array. Therefore I can use this:
this.$children[problem_index].recompute_entry();
Which kind of feels hack-ish and unreliable, but actually works, for once. Is there no alternative safer method to recalculate my child components based on changes made to their props? I really feel there has to be.
vue.js vue-component parent-child vue-reactivity
I am currently generating a table which lists problems encountered during the selected test using a component generated with this code:
<tr is="entry" v-for="problem in problems" :key="problem.id" v-bind:foo="problem"></tr>
Each problem corresponds to an item whose relevant information is contained within the problem dictionary and referenced in the first few columns of the table. Since the same item can have multiple problems, the same item can appear in multiple rows of the table. Now, each row features some buttons which allow you to modify the underlying item so as to fix the problems.
Whenever I modify one of those underlying items I need to modify it in all the rows, which i do by calling a function in the parent component, but modifying the data inside of the dictionary does not seem to trigger any of my watches or computes inside of the child component, which currently looks something like this:
Vue.component('entry', {
props: ['foo'],
data: function(){
//does some computations
return data
},
watch:{
foo: function(){
this.recompute_entry()
},
},
methods:{
//various methods, including:
recompute_entry: function(){
//updates the data according to changes brought to the entry
},
},
});
I have attempted to include a different prop which i could bind to an entry in a list in my parent component but, besides being pretty clunky, that didn't end up working either, which makes me think I might've gotten something wrong with my component.
Ultimately, I have relied on the fact that v-for iterates through my list in an orderly fashion, which combined with the fact that I generate no other children in my parent component means that a child component would have the same index in my component's children array as it would in my problems array. Therefore I can use this:
this.$children[problem_index].recompute_entry();
Which kind of feels hack-ish and unreliable, but actually works, for once. Is there no alternative safer method to recalculate my child components based on changes made to their props? I really feel there has to be.
vue.js vue-component parent-child vue-reactivity
vue.js vue-component parent-child vue-reactivity
asked Nov 22 at 16:06
2spriggan49
61
61
2
Consider using [vuex|vuex.vuejs.org/] to store your data as your application's "state" and define mutations/getters to modify/access it. they have very nice examples in their github such as github.com/vuejs/vuex/tree/dev/examples/shopping-cart
– mmbrian
Nov 22 at 16:23
add a comment |
2
Consider using [vuex|vuex.vuejs.org/] to store your data as your application's "state" and define mutations/getters to modify/access it. they have very nice examples in their github such as github.com/vuejs/vuex/tree/dev/examples/shopping-cart
– mmbrian
Nov 22 at 16:23
2
2
Consider using [vuex|vuex.vuejs.org/] to store your data as your application's "state" and define mutations/getters to modify/access it. they have very nice examples in their github such as github.com/vuejs/vuex/tree/dev/examples/shopping-cart
– mmbrian
Nov 22 at 16:23
Consider using [vuex|vuex.vuejs.org/] to store your data as your application's "state" and define mutations/getters to modify/access it. they have very nice examples in their github such as github.com/vuejs/vuex/tree/dev/examples/shopping-cart
– mmbrian
Nov 22 at 16:23
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
I probably would need to see the exact implementation but it sounds like you need to clone your dictionary to trigger the prop change, ie:
let newProblem = Object.assign({}, this.problem);
// change any nested property
newProblem.some.value = 1
// assign back the cloned and modified dictionary
this.problem = newProblem
The exact implementation is around 500 lines of code, which is why I tried to avoid posting all of it. For what it's worth, I had already tried creating a new dictionary and assigning it to the problem, but I'm assuming the issue lies in the fact that the problem itself is inside of a list. If i reassign all of that I'd have to re-render the entire table, which would be too costly.
– 2spriggan49
Nov 23 at 10:20
Whoa, having 500 lines of code and also having all that data is a good sign that you should be breaking up that component into more components. Probably you can do it in a way that each child takes care of their own data with their own local state so that you don't need to re-render everything.
– EderChrono
Nov 23 at 17:28
That's including all my methods for filtering or sending data to the server, not just rendering and declaring my data. The gist of it absolutely boils down to the code I included in the original question really. Everything that's really missing is some filtering that is done wherein i use problems.push(element);` to add to my final list i build my entries out of, but I didn't consider that relevant.
– 2spriggan49
Nov 26 at 16:17
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
I probably would need to see the exact implementation but it sounds like you need to clone your dictionary to trigger the prop change, ie:
let newProblem = Object.assign({}, this.problem);
// change any nested property
newProblem.some.value = 1
// assign back the cloned and modified dictionary
this.problem = newProblem
The exact implementation is around 500 lines of code, which is why I tried to avoid posting all of it. For what it's worth, I had already tried creating a new dictionary and assigning it to the problem, but I'm assuming the issue lies in the fact that the problem itself is inside of a list. If i reassign all of that I'd have to re-render the entire table, which would be too costly.
– 2spriggan49
Nov 23 at 10:20
Whoa, having 500 lines of code and also having all that data is a good sign that you should be breaking up that component into more components. Probably you can do it in a way that each child takes care of their own data with their own local state so that you don't need to re-render everything.
– EderChrono
Nov 23 at 17:28
That's including all my methods for filtering or sending data to the server, not just rendering and declaring my data. The gist of it absolutely boils down to the code I included in the original question really. Everything that's really missing is some filtering that is done wherein i use problems.push(element);` to add to my final list i build my entries out of, but I didn't consider that relevant.
– 2spriggan49
Nov 26 at 16:17
add a comment |
up vote
0
down vote
I probably would need to see the exact implementation but it sounds like you need to clone your dictionary to trigger the prop change, ie:
let newProblem = Object.assign({}, this.problem);
// change any nested property
newProblem.some.value = 1
// assign back the cloned and modified dictionary
this.problem = newProblem
The exact implementation is around 500 lines of code, which is why I tried to avoid posting all of it. For what it's worth, I had already tried creating a new dictionary and assigning it to the problem, but I'm assuming the issue lies in the fact that the problem itself is inside of a list. If i reassign all of that I'd have to re-render the entire table, which would be too costly.
– 2spriggan49
Nov 23 at 10:20
Whoa, having 500 lines of code and also having all that data is a good sign that you should be breaking up that component into more components. Probably you can do it in a way that each child takes care of their own data with their own local state so that you don't need to re-render everything.
– EderChrono
Nov 23 at 17:28
That's including all my methods for filtering or sending data to the server, not just rendering and declaring my data. The gist of it absolutely boils down to the code I included in the original question really. Everything that's really missing is some filtering that is done wherein i use problems.push(element);` to add to my final list i build my entries out of, but I didn't consider that relevant.
– 2spriggan49
Nov 26 at 16:17
add a comment |
up vote
0
down vote
up vote
0
down vote
I probably would need to see the exact implementation but it sounds like you need to clone your dictionary to trigger the prop change, ie:
let newProblem = Object.assign({}, this.problem);
// change any nested property
newProblem.some.value = 1
// assign back the cloned and modified dictionary
this.problem = newProblem
I probably would need to see the exact implementation but it sounds like you need to clone your dictionary to trigger the prop change, ie:
let newProblem = Object.assign({}, this.problem);
// change any nested property
newProblem.some.value = 1
// assign back the cloned and modified dictionary
this.problem = newProblem
answered Nov 22 at 18:22
EderChrono
1847
1847
The exact implementation is around 500 lines of code, which is why I tried to avoid posting all of it. For what it's worth, I had already tried creating a new dictionary and assigning it to the problem, but I'm assuming the issue lies in the fact that the problem itself is inside of a list. If i reassign all of that I'd have to re-render the entire table, which would be too costly.
– 2spriggan49
Nov 23 at 10:20
Whoa, having 500 lines of code and also having all that data is a good sign that you should be breaking up that component into more components. Probably you can do it in a way that each child takes care of their own data with their own local state so that you don't need to re-render everything.
– EderChrono
Nov 23 at 17:28
That's including all my methods for filtering or sending data to the server, not just rendering and declaring my data. The gist of it absolutely boils down to the code I included in the original question really. Everything that's really missing is some filtering that is done wherein i use problems.push(element);` to add to my final list i build my entries out of, but I didn't consider that relevant.
– 2spriggan49
Nov 26 at 16:17
add a comment |
The exact implementation is around 500 lines of code, which is why I tried to avoid posting all of it. For what it's worth, I had already tried creating a new dictionary and assigning it to the problem, but I'm assuming the issue lies in the fact that the problem itself is inside of a list. If i reassign all of that I'd have to re-render the entire table, which would be too costly.
– 2spriggan49
Nov 23 at 10:20
Whoa, having 500 lines of code and also having all that data is a good sign that you should be breaking up that component into more components. Probably you can do it in a way that each child takes care of their own data with their own local state so that you don't need to re-render everything.
– EderChrono
Nov 23 at 17:28
That's including all my methods for filtering or sending data to the server, not just rendering and declaring my data. The gist of it absolutely boils down to the code I included in the original question really. Everything that's really missing is some filtering that is done wherein i use problems.push(element);` to add to my final list i build my entries out of, but I didn't consider that relevant.
– 2spriggan49
Nov 26 at 16:17
The exact implementation is around 500 lines of code, which is why I tried to avoid posting all of it. For what it's worth, I had already tried creating a new dictionary and assigning it to the problem, but I'm assuming the issue lies in the fact that the problem itself is inside of a list. If i reassign all of that I'd have to re-render the entire table, which would be too costly.
– 2spriggan49
Nov 23 at 10:20
The exact implementation is around 500 lines of code, which is why I tried to avoid posting all of it. For what it's worth, I had already tried creating a new dictionary and assigning it to the problem, but I'm assuming the issue lies in the fact that the problem itself is inside of a list. If i reassign all of that I'd have to re-render the entire table, which would be too costly.
– 2spriggan49
Nov 23 at 10:20
Whoa, having 500 lines of code and also having all that data is a good sign that you should be breaking up that component into more components. Probably you can do it in a way that each child takes care of their own data with their own local state so that you don't need to re-render everything.
– EderChrono
Nov 23 at 17:28
Whoa, having 500 lines of code and also having all that data is a good sign that you should be breaking up that component into more components. Probably you can do it in a way that each child takes care of their own data with their own local state so that you don't need to re-render everything.
– EderChrono
Nov 23 at 17:28
That's including all my methods for filtering or sending data to the server, not just rendering and declaring my data. The gist of it absolutely boils down to the code I included in the original question really. Everything that's really missing is some filtering that is done wherein i use problems.push(element);` to add to my final list i build my entries out of, but I didn't consider that relevant.
– 2spriggan49
Nov 26 at 16:17
That's including all my methods for filtering or sending data to the server, not just rendering and declaring my data. The gist of it absolutely boils down to the code I included in the original question really. Everything that's really missing is some filtering that is done wherein i use problems.push(element);` to add to my final list i build my entries out of, but I didn't consider that relevant.
– 2spriggan49
Nov 26 at 16:17
add a comment |
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434709%2fvue-forcing-child-component-to-react-to-changes-in-its-prop-which-is-a-diction%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
2
Consider using [vuex|vuex.vuejs.org/] to store your data as your application's "state" and define mutations/getters to modify/access it. they have very nice examples in their github such as github.com/vuejs/vuex/tree/dev/examples/shopping-cart
– mmbrian
Nov 22 at 16:23