component cannot find action - ember.js

I have a component that has a text field, like this
<div>
{{input type='text' insert-newline='postMessage' class="form-control" autofocus="true"}}
<input type="hidden" name="uid" value={{room.uid}}/>
</div>
the component that have this snippet, lives inside a route called room
export default Ember.Route.extend({
model(params){
this.store.findRecord('room', params.uid);
}
});
to handle the action in the input, I created a controller for the room:
app/controllers/room.js
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
postMessage(params){
console.log(params);
}
}
});
but when I hit enter, I get this error:
Uncaught Error: <chathub-ember#component:chat-room::ember1071> had no action handler for: postMessage
I tried to put this action in the route as well and didn't worked

In the room.hbs file,
{{my-component myAction='postMessage'}}
and then in my-component.js
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
postMessage(params) {
this.sendAction('myAction', params);
}
}
})

Related

How can we get the original event in ember controller action

How can we get the original event in ember action while handling action inside controller?
Controller
import Ember from 'ember';
export default Controller.extend({
showDetails:function(id)
{
// I want like $(this).position().top
}
});
Template
{{#each item in list}}
<em {{action "showDetails" item.id bubbles=false}}></em>
{{/each}}
{{#each item in list}}
<em onclick={{action "showDetails" item.id}}></em>
{{/each}}
In controller,
import Ember from 'ember';
export default Controller.extend({
actions: {
showDetails(id, event) {
//i want like $(this).position().top
}
}
});

How to bind Route Property to Controller so that route property changes will reflect in controller

Changing isOpen property in route should reflect it in my component. How can we accomplish this ?.
Ember-Twiddle
routes/application.js
import Ember from 'ember';
export default Ember.Route.extend({
isOpen:true,
setupController(controller,model){
this._super(...arguments);
controller.set('isOpen',this.get('isOpen')); //whenever i set route property, will this update controller?
console.log('setupController');
},
actions:{
toggleOpen(){
console.log('before toggle - ',this.get('isOpen'));
this.toggleProperty('isOpen'); //changing this route property is not reflected in controller.
//this.controller.toggleProperty('isOpen'); //changing controller is reflecting.
console.log('after toggle - ',this.get('isOpen'));
}
}
});
controllers/application.js
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle'
});
templates/application.hbs
<h1>Welcome to {{appName}}</h1>
<br>
{{isOpen}}
{{my-component isOpen=isOpen toggleOpen='toggleOpen'}}
<br>
{{outlet}}
<br>
<br>
templates/components/my-component.hbs
my-component {{isOpen}}
<button {{action 'toggleOpen'}}> Toggle </button>
{{yield}}
components/my-component.js
import Ember from 'ember';
export default Ember.Component.extend({
actions:{
toggleOpen(){
this.sendAction('toggleOpen');
}
}
});
Because isOpen is a primitive typed property. No matter if it was an object. Sample Twiddle.
Or more simplistic one.

Call action from parent component in Ember 2.x

I am trying to call an action from a parent component in my route view.
mychild.hbs
{{#parent as |wrapper|}}
<button {{action "animate"}}>Login</button>
{{/parent}}
parent.hbs
<div>{{yield}}</div>
mychild route (no actions)
export default Ember.Route.extend(
});
mychild controller
export default Ember.Controller.extend({
});
parent component
export default Ember.Component.extend({
actions: {
animate() {
console.log('ok');
}
},
});
How to call animate() from my component ? What am I doing wrong ?
Changed the following code to this. Seems to be working.
<div>
{{yield this}}
</div>
{{#my-component as |mc|}}
<button {{action "doIt" target=mc}}>callDoIt</button>
{{/my-component}}

How can I update component value in controller or route with ember?

My click-editable component like:
Template:
{{#if isEdit}}
<div class="input-group">
{{input type="text" value=editValue class="form-control"}}
<div class="input-group-btn">
<button type="button" class="btn no-margin-btn btn-info" {{action "updateValue"}}>{{fa-icon 'check'}}</button>
</div>
</div>
{{else}}
....
{{/if}}
And:
export default Ember.Component.extend({
tagName: "",
isEdit: false,
canEdit: true,
category: 'input',
editValue: Ember.computed.oneWay('value'),
actions:{
updateValue() {
this.sendAction('onUpdate', this.get('valueModel'), this.get('valueColumn'), this.get('editValue'), this.get('isEdit'));
}
}
});
Use in my template:
{{#each model.quotationWorkItems as |quotationWorkItem index|}}
{{click-editable valueModel=quotationWorkItem valueColumn='name' value=quotationWorkItem.name onUpdate=(action "updateInput")}}
{{/each}}
In the controller:
import Ember from 'ember';
export default Ember.Controller.extend({
....
actions: {
updateInput(updateModel, updateColumn, value, isEdit) {
updateModel.set(updateColumn, value);
updateModel.save().then(()=> {
this.get('model').reload();
this.set('isEdit', false);
}, ()=> {
alert('wrong');
});
}
}
})
Route:
import Ember from 'ember';
export default Ember.Route.extend({
...
model(params) {
return this.store.find('quotation', params.quotation_id);
},
setupController(controller, model) {
controller.set('model', model);
...
}
})
Quotation model:
import DS from 'ember-data';
export default DS.Model.extend({
quotationStocks: DS.hasMany('quotationStock'),
quotationWorkItems: DS.hasMany('quotationWorkItem'),
...
});
QuotationWorkItem model:
import DS from 'ember-data';
export default DS.Model.extend({
transactionType: DS.belongsTo('transactionType'),
quotation: DS.belongsTo('quotation'),
...
});
This code can update model value, but problem isEdit is the component value. When isEdit send to controller and set another value, it can not work. So I think can not change component value in ember controller?
this.set('isEdit', false);
The code can not work in controller. I'm using Ember 2.4.0.
You need to bind the controller isEdit property to the component isEdit property.
{{click-editable isEdit=isEdit valueModel=quotationWorkItem valueColumn='name' value=quotationWorkItem.name onUpdate=(action "updateInput")}}
This will overwrite the isEdit property in the component (data down).

Access jquery event from ember component action

I'm trying to work with a simple overlay component, and close this overlay if someone clicks outside of the overlay content:
<div class="overlay" {{action 'close' on='click'}}>
<div class="item">
<form {{action 'submit' on='submit'}}>
{{yield}}
{{#link-to closeRoute class="close"}}Close{{/link-to}}
</form>
</div>
</div>
The component looks like this:
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
submit: function() {
this.sendAction();
},
close: function(param) {
console.log(param); // -> undefined
console.log(this); // -> complete component object, no reference to the event?
// this.$("a.close").click();
}
}
});
This works like advertised, however, I need to determine the target of the click event, because also clicks on the item and form will trigger this click(close) action.
Question: How can I access the (jQuery) event object which has a target from within the close action inside the component?
I am using EmberCLI, and Ember 1.9
I have found this to provide the required result:
export default Ember.Component.extend({
classNames: ['overlay-block'],
didInsertElement: function() {
var self = this;
self.$().click(function(e) {
if (self.$(e.target).hasClass("overlay-block")) {
self.$("a.close").click();
}
});
}
});
This does not use an ember action like I expected. I'll leave the question open for a while to see if somebody comes up with an more 'Ember way' of doing this.
More Ember way
export default Ember.Component.extend({
classNames: ['overlay-block'],
click: function(e) {
if (this.$(e.target).hasClass("overlay-block")){
this.$("a.close").click();
}
}
});