I can't seem to get a button, generated within an #each
template loop, to bind its click action to its associated model. Here's a quick demo of the problem...
The Ember.js
app setup:
window.Contacts = Ember.Application.create();
Contacts.Person = Ember.Object.extend({
first: '',
last: '',
save: function() {
// send updated information to server.
}
});
Contacts.contactsList = Ember.ArrayController.create({
content:[],
init: function() {
this.pushObject( Contacts.Person.create({
first:'Tom',
last:'Riddle'
}));
}
});
The template:
<script type="text/x-handlebars">
{{#each Contacts.contactsList}}
<li>
{{view Ember.TextField valueBinding="first" viewName="firstname"}}
{{view Ember.TextField valueBinding="last" viewName="lastname"}}
<button {{action "save" on="click"}}>Save</button>
</li>
{{/each}}
</script>
The problem:
So, the idea in this simple demo scenario is that the "Save" button for each record will trigger an action to save the state of its own model. However, clicking the Save button gives an error:
Uncaught TypeError: Cannot call method 'call' of undefined
My assumption would be that specifying "save" as the button's action would bind it to the save
method on its model. However, this does not appear to be the case. Some other object appears to be handling click actions, wherein a "save" hander is undefined. Am I missing something here? How could I make each line item's button call a handler on its own model?
Thanks in advance for any help!
You can define a target of an action by setting the - surprise - target
property, see http://jsfiddle.net/pangratz666/FukKX/:
<script type="text/x-handlebars" >
{{#each Contacts.contactsList}}
<li>
{{view Ember.TextField valueBinding="first" viewName="firstname"}}
{{view Ember.TextField valueBinding="last" viewName="lastname"}}
{{#with this as model}}
<button {{action "save" target="model"}}>Save</button>
{{/with}}
</li>
{{/each}}
</script>
The {{#with}}
helper around the action is needed because somehow the action helper does not accept this
as a target
.
But a note to your design: actions should be called on views or on a controller. The target is then responsible for executing further actions like saving, ...
So I would implement your example as follows, see http://jsfiddle.net/pangratz666/U2TKJ/:
Handlebars:
<script type="text/x-handlebars" >
{{#each Contacts.contactsList}}
<li>
{{view Ember.TextField valueBinding="first" viewName="firstname"}}
{{view Ember.TextField valueBinding="last" viewName="lastname"}}
<button {{action "save" target="Contacts.contactsController" }}>Save</button>
</li>
{{/each}}
</script>
JavaScript:
Contacts.contactsController = Ember.Object.create({
save: function(event) {
console.log('do something with: ', event.context);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With