Reputation: 3
In my Ember component, I have a list of strings, and a function that update the string at certain index of the list.
animals: computed(function() {
return ["dog", "cat"];
}),
updateAnimal(value, index) {
this.animals[index] = value;
},
In my hbs, I render the list of strings into text fields, within a #each
loop. When I focus-out
the text field, I want to update the string at the certain index.
{{#each animals as |animal index|}}
<textarea
value={{animal}}
{{on "focusout" (action updateAnimal value="details.value")}}
/>
{{/each}}
But how can I pass in the index to the handler as well? In other words, how can I pass the event and some extra parameter at the same time? Thanks a lot for answering my question!!
Upvotes: 0
Views: 1618
Reputation: 6338
You can applay arguments to an action using the {{fn}}
helper:
{{#each this.animals as |animal|}}
<textarea {{on "focusout" (fn this.updateValue animal)}} />
{{/each}}
The updateValue
method will receive the animal
as first argument and the event as the second argument.
import Component from '@glimmer/component';
import { action } from '@ember/object';
export default class MyComponent extends Component {
animals = ['dog', 'cat'];
@action
updateAnimal(animal, event) {
const { value } = event.target;
window.alert(`Changed text for animal ${animal} to ${value}`);
}
}
Please see this Ember Twiddle for the code running: https://ember-twiddle.com/cad87d51ec2e1fdfd88b8a123ba2d7dd?openFiles=components.my-component%5C.js%2Ctemplates.components.my-component%5C.hbs
Please note that I modernized your code using Ember Octane primitives. I used native classes, dropped computed property in favor or class field, avoided implicit this
fallback in template and used @action
decorator for binding this
context. It should work similar with the old patterns used in your question. But I think the new Octane primitives are easier to understand.
Upvotes: 1