Ember: Send child component's action to a parent component
I am trying to call/trigger a child component's action from a parent. I've tried this a couple ways but I'm not getting anywhere. This is basically what I have so far.
I am attempting to send the action up to the parent by passing it as a parameter in the action that was passed down...
This seems a bit like a spaghetti situation but the way my project is organized, this is my result.
If anyone could, please tell me how to successfully pass an action up to the parent as a parameter. (I'm curious to know how, if possible)
If anyone also has a better suggestion on how to call a child's action, please share. Thanks in advance!
parent-component.hbs
{{child-component anAction=(action "anAction")}}
<div onclick={{action actionPassedFromChild}}></div>
parent-component.js
actionPassedFromChild: null,
....
actions: {
parentAction(childAction){
this.set('actionPassedFromChild', childAction);
}
}
child-component.hbs
<div onclick={{action "anAction"}}
child-component.js
....
actions: {
anAction(){
this.parentAction(childAction);
}
childAction(){
//Some operation
}
}
In this example, if I stop the code inside of 'anAction', I do have 'childAction'. But by the time that it gets passed into 'parentAction', it is undefined. Could anyone explain why?
javascript ember.js handlebars.js action
add a comment |
I am trying to call/trigger a child component's action from a parent. I've tried this a couple ways but I'm not getting anywhere. This is basically what I have so far.
I am attempting to send the action up to the parent by passing it as a parameter in the action that was passed down...
This seems a bit like a spaghetti situation but the way my project is organized, this is my result.
If anyone could, please tell me how to successfully pass an action up to the parent as a parameter. (I'm curious to know how, if possible)
If anyone also has a better suggestion on how to call a child's action, please share. Thanks in advance!
parent-component.hbs
{{child-component anAction=(action "anAction")}}
<div onclick={{action actionPassedFromChild}}></div>
parent-component.js
actionPassedFromChild: null,
....
actions: {
parentAction(childAction){
this.set('actionPassedFromChild', childAction);
}
}
child-component.hbs
<div onclick={{action "anAction"}}
child-component.js
....
actions: {
anAction(){
this.parentAction(childAction);
}
childAction(){
//Some operation
}
}
In this example, if I stop the code inside of 'anAction', I do have 'childAction'. But by the time that it gets passed into 'parentAction', it is undefined. Could anyone explain why?
javascript ember.js handlebars.js action
add a comment |
I am trying to call/trigger a child component's action from a parent. I've tried this a couple ways but I'm not getting anywhere. This is basically what I have so far.
I am attempting to send the action up to the parent by passing it as a parameter in the action that was passed down...
This seems a bit like a spaghetti situation but the way my project is organized, this is my result.
If anyone could, please tell me how to successfully pass an action up to the parent as a parameter. (I'm curious to know how, if possible)
If anyone also has a better suggestion on how to call a child's action, please share. Thanks in advance!
parent-component.hbs
{{child-component anAction=(action "anAction")}}
<div onclick={{action actionPassedFromChild}}></div>
parent-component.js
actionPassedFromChild: null,
....
actions: {
parentAction(childAction){
this.set('actionPassedFromChild', childAction);
}
}
child-component.hbs
<div onclick={{action "anAction"}}
child-component.js
....
actions: {
anAction(){
this.parentAction(childAction);
}
childAction(){
//Some operation
}
}
In this example, if I stop the code inside of 'anAction', I do have 'childAction'. But by the time that it gets passed into 'parentAction', it is undefined. Could anyone explain why?
javascript ember.js handlebars.js action
I am trying to call/trigger a child component's action from a parent. I've tried this a couple ways but I'm not getting anywhere. This is basically what I have so far.
I am attempting to send the action up to the parent by passing it as a parameter in the action that was passed down...
This seems a bit like a spaghetti situation but the way my project is organized, this is my result.
If anyone could, please tell me how to successfully pass an action up to the parent as a parameter. (I'm curious to know how, if possible)
If anyone also has a better suggestion on how to call a child's action, please share. Thanks in advance!
parent-component.hbs
{{child-component anAction=(action "anAction")}}
<div onclick={{action actionPassedFromChild}}></div>
parent-component.js
actionPassedFromChild: null,
....
actions: {
parentAction(childAction){
this.set('actionPassedFromChild', childAction);
}
}
child-component.hbs
<div onclick={{action "anAction"}}
child-component.js
....
actions: {
anAction(){
this.parentAction(childAction);
}
childAction(){
//Some operation
}
}
In this example, if I stop the code inside of 'anAction', I do have 'childAction'. But by the time that it gets passed into 'parentAction', it is undefined. Could anyone explain why?
javascript ember.js handlebars.js action
javascript ember.js handlebars.js action
edited Nov 16 '18 at 19:19
asked Nov 16 '18 at 19:11
Nate Thompson
425
425
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It seems like you have some typos. For example, parentAction is not passed to child component. But if I understood what do you want to achieve right - it is doable, however I can't even imagine why you might need this.
You can play with my example here. Select is in child component and button is in parent component. When you choose something in select - child component sends one of two functions to parent component. And when you click a button - parent component calls that function.
Code:
//child-component.js
import Ember from 'ember';
export default Ember.Component.extend({
line1: "Say Hi!",
line2: "Say Yeah!",
changeAction(newAction) {
switch (newAction) {
case "1":
this.onActionChange(this.action1);
break;
case "2":
this.onActionChange(this.action2);
break;
default:
this.onActionChange(undefined);
break;
}
},
action1: Ember.computed(function(){
const that = this;
return function() {
alert(that.line1);
}
}),
action2: Ember.computed(function(){
const that = this;
return function() {
alert(that.line2);
}
})
});
//child-component.hbs
<select onchange={{action changeAction value="target.value"}}>
<option>Choose something</option>
<option value="1">Action 1</option>
<option value="2">Action 2</option>
</select>
//parent-component.js
import Ember from 'ember';
export default Ember.Component.extend({
childishAction() {
if (typeof this.childAction === 'function') {
this.childAction();
}
}
});
//parent-component.hbs
{{child-component onActionChange=(action (mut childAction))}}
<div><button disabled={{unless childAction true false}} onclick={{action childishAction}}>Let's do it!</button></div>
What happens here - you can't pass to action
helper something that is not defined when ember renders template. So you need to store action that child-component sends into some variable and call it using some intermediate action of parent component.
In my example, function returned from child component is stored in childAction property of parent component and childishAction
of parent component calls it.
Hope this helps. But you probably trying to solve some problem in not a right way.
Assigning the child function to a property helped. Thank you!
– Nate Thompson
Nov 16 '18 at 20:32
add a comment |
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
});
}
});
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%2f53344020%2fember-send-child-components-action-to-a-parent-component%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
It seems like you have some typos. For example, parentAction is not passed to child component. But if I understood what do you want to achieve right - it is doable, however I can't even imagine why you might need this.
You can play with my example here. Select is in child component and button is in parent component. When you choose something in select - child component sends one of two functions to parent component. And when you click a button - parent component calls that function.
Code:
//child-component.js
import Ember from 'ember';
export default Ember.Component.extend({
line1: "Say Hi!",
line2: "Say Yeah!",
changeAction(newAction) {
switch (newAction) {
case "1":
this.onActionChange(this.action1);
break;
case "2":
this.onActionChange(this.action2);
break;
default:
this.onActionChange(undefined);
break;
}
},
action1: Ember.computed(function(){
const that = this;
return function() {
alert(that.line1);
}
}),
action2: Ember.computed(function(){
const that = this;
return function() {
alert(that.line2);
}
})
});
//child-component.hbs
<select onchange={{action changeAction value="target.value"}}>
<option>Choose something</option>
<option value="1">Action 1</option>
<option value="2">Action 2</option>
</select>
//parent-component.js
import Ember from 'ember';
export default Ember.Component.extend({
childishAction() {
if (typeof this.childAction === 'function') {
this.childAction();
}
}
});
//parent-component.hbs
{{child-component onActionChange=(action (mut childAction))}}
<div><button disabled={{unless childAction true false}} onclick={{action childishAction}}>Let's do it!</button></div>
What happens here - you can't pass to action
helper something that is not defined when ember renders template. So you need to store action that child-component sends into some variable and call it using some intermediate action of parent component.
In my example, function returned from child component is stored in childAction property of parent component and childishAction
of parent component calls it.
Hope this helps. But you probably trying to solve some problem in not a right way.
Assigning the child function to a property helped. Thank you!
– Nate Thompson
Nov 16 '18 at 20:32
add a comment |
It seems like you have some typos. For example, parentAction is not passed to child component. But if I understood what do you want to achieve right - it is doable, however I can't even imagine why you might need this.
You can play with my example here. Select is in child component and button is in parent component. When you choose something in select - child component sends one of two functions to parent component. And when you click a button - parent component calls that function.
Code:
//child-component.js
import Ember from 'ember';
export default Ember.Component.extend({
line1: "Say Hi!",
line2: "Say Yeah!",
changeAction(newAction) {
switch (newAction) {
case "1":
this.onActionChange(this.action1);
break;
case "2":
this.onActionChange(this.action2);
break;
default:
this.onActionChange(undefined);
break;
}
},
action1: Ember.computed(function(){
const that = this;
return function() {
alert(that.line1);
}
}),
action2: Ember.computed(function(){
const that = this;
return function() {
alert(that.line2);
}
})
});
//child-component.hbs
<select onchange={{action changeAction value="target.value"}}>
<option>Choose something</option>
<option value="1">Action 1</option>
<option value="2">Action 2</option>
</select>
//parent-component.js
import Ember from 'ember';
export default Ember.Component.extend({
childishAction() {
if (typeof this.childAction === 'function') {
this.childAction();
}
}
});
//parent-component.hbs
{{child-component onActionChange=(action (mut childAction))}}
<div><button disabled={{unless childAction true false}} onclick={{action childishAction}}>Let's do it!</button></div>
What happens here - you can't pass to action
helper something that is not defined when ember renders template. So you need to store action that child-component sends into some variable and call it using some intermediate action of parent component.
In my example, function returned from child component is stored in childAction property of parent component and childishAction
of parent component calls it.
Hope this helps. But you probably trying to solve some problem in not a right way.
Assigning the child function to a property helped. Thank you!
– Nate Thompson
Nov 16 '18 at 20:32
add a comment |
It seems like you have some typos. For example, parentAction is not passed to child component. But if I understood what do you want to achieve right - it is doable, however I can't even imagine why you might need this.
You can play with my example here. Select is in child component and button is in parent component. When you choose something in select - child component sends one of two functions to parent component. And when you click a button - parent component calls that function.
Code:
//child-component.js
import Ember from 'ember';
export default Ember.Component.extend({
line1: "Say Hi!",
line2: "Say Yeah!",
changeAction(newAction) {
switch (newAction) {
case "1":
this.onActionChange(this.action1);
break;
case "2":
this.onActionChange(this.action2);
break;
default:
this.onActionChange(undefined);
break;
}
},
action1: Ember.computed(function(){
const that = this;
return function() {
alert(that.line1);
}
}),
action2: Ember.computed(function(){
const that = this;
return function() {
alert(that.line2);
}
})
});
//child-component.hbs
<select onchange={{action changeAction value="target.value"}}>
<option>Choose something</option>
<option value="1">Action 1</option>
<option value="2">Action 2</option>
</select>
//parent-component.js
import Ember from 'ember';
export default Ember.Component.extend({
childishAction() {
if (typeof this.childAction === 'function') {
this.childAction();
}
}
});
//parent-component.hbs
{{child-component onActionChange=(action (mut childAction))}}
<div><button disabled={{unless childAction true false}} onclick={{action childishAction}}>Let's do it!</button></div>
What happens here - you can't pass to action
helper something that is not defined when ember renders template. So you need to store action that child-component sends into some variable and call it using some intermediate action of parent component.
In my example, function returned from child component is stored in childAction property of parent component and childishAction
of parent component calls it.
Hope this helps. But you probably trying to solve some problem in not a right way.
It seems like you have some typos. For example, parentAction is not passed to child component. But if I understood what do you want to achieve right - it is doable, however I can't even imagine why you might need this.
You can play with my example here. Select is in child component and button is in parent component. When you choose something in select - child component sends one of two functions to parent component. And when you click a button - parent component calls that function.
Code:
//child-component.js
import Ember from 'ember';
export default Ember.Component.extend({
line1: "Say Hi!",
line2: "Say Yeah!",
changeAction(newAction) {
switch (newAction) {
case "1":
this.onActionChange(this.action1);
break;
case "2":
this.onActionChange(this.action2);
break;
default:
this.onActionChange(undefined);
break;
}
},
action1: Ember.computed(function(){
const that = this;
return function() {
alert(that.line1);
}
}),
action2: Ember.computed(function(){
const that = this;
return function() {
alert(that.line2);
}
})
});
//child-component.hbs
<select onchange={{action changeAction value="target.value"}}>
<option>Choose something</option>
<option value="1">Action 1</option>
<option value="2">Action 2</option>
</select>
//parent-component.js
import Ember from 'ember';
export default Ember.Component.extend({
childishAction() {
if (typeof this.childAction === 'function') {
this.childAction();
}
}
});
//parent-component.hbs
{{child-component onActionChange=(action (mut childAction))}}
<div><button disabled={{unless childAction true false}} onclick={{action childishAction}}>Let's do it!</button></div>
What happens here - you can't pass to action
helper something that is not defined when ember renders template. So you need to store action that child-component sends into some variable and call it using some intermediate action of parent component.
In my example, function returned from child component is stored in childAction property of parent component and childishAction
of parent component calls it.
Hope this helps. But you probably trying to solve some problem in not a right way.
edited Nov 16 '18 at 20:27
answered Nov 16 '18 at 20:21
Gennady Dogaev
3,8971818
3,8971818
Assigning the child function to a property helped. Thank you!
– Nate Thompson
Nov 16 '18 at 20:32
add a comment |
Assigning the child function to a property helped. Thank you!
– Nate Thompson
Nov 16 '18 at 20:32
Assigning the child function to a property helped. Thank you!
– Nate Thompson
Nov 16 '18 at 20:32
Assigning the child function to a property helped. Thank you!
– Nate Thompson
Nov 16 '18 at 20:32
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%2f53344020%2fember-send-child-components-action-to-a-parent-component%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