问题
I have a set of buttons whose state I wish to toggle with a class active
. If I had a single button, then I would bind the active
class to a controller property and toggle that property in the click handler:
<button {{action 'toggle'}} class="{{active}}">model.title</button>
actions: {
toggle: function() {
this.set('active', true);
}
}
But I have multiple buttons, so I am not sure what I can bind. It would be useful if I could pass a reference to the clicked button to the action handler, but I'm not sure how to do this.
{{#each item in model}}
<button {{action 'toggle' referenceToButton}}>model.title</button>
{{/each}}
actions: {
toggle: function(buttonReference) {
// add `active` class to buttonReference
}
}
What is the best way to accomplish this?
回答1:
Isn't the model-item what you want to pass and not the button?
Then your toggle can just set an attribute on the item which you bind to your button class.
{{#each item in model}}
<button {{bind-attr class="item.isActive:active"}} {{action 'toggle' item}}>model.title</button>
{{/each}}
actions: {
toggle: function(item) {
item.set('isActive', true);
}
}
回答2:
Even though the poster got the answer he wanted, I thought I'd post an answer to what I believe was the intention of the original question:
How to get a reference the clicked DOM element from an action? since I came here looking for an answer to that question and didn't find it.
I can't find a way to get the actual element, but you can get the root view element (which wraps the elements defined in the template) via this
:
template:
<button {{action 'toggle' this}}>model.title</button>
controller, view, component:
actions: {
toggle: function(event) {
// Get element (as in the return value of document.getElementById(id))
var viewElements = event.element;
var elementsInTemplate = viewElements.children;
var button = viewElements.getElementsByTagName('button');
//also can use getElementsByClassName, use jQuery etc.
}
}
回答3:
Just another answer...
if you put the action in the onclick (or any other dom event) you will get the "event" javascript object in the last parameter (so you can use event.target to get and manipulate the object)
Template:
<button onclick={{action 'toggle' model.title}}>model.title</button>
Route or controller:
actions: {
toggle (title, event) {
// TODO: use title
let element = Ember.$(event.target);
element.toggleClass("active");
return false;
}
}
Hope it helps
回答4:
You can introduce active
property to items
{{#each item as |model|}}
<button {{action 'toggle' model}} class={{if model.active 'active'}}>{{model.title}}</button>
{{/each}}
if active=true
then active
class will be applied to button.
actions: {
toggle: function(buttonReference) {
buttonReference.set('active', true);
}
}
To answer the question title Pass a reference of the clicked DOM element to the action handler in Ember
.
1.If you are using component, then you can define any of this list of event names in component and that is designed to receive native event
object.
eg.,
{{my-button model=model}}
export default Ember.Component.extend({
click(event){
//oncliking on this componen will trigger this function
return true; //to bubble this event up
}
})
2.If you are using html tag like button
then you need to assign a (closure) action to an inline event handler.
{{#each item as |model|}}
<button onclick={{action 'toggle' model}}>{{model.title}}</button>
{{/each}}
In actions hash toggle
function will always receive native browser event
object as the last argument.
actions:{
toggle(model,event){
}
}
In this <button {{action 'toggle' model}}>{{model.title}}</button>
format, action toggle
will not receive event
object,
Explained really well in ember guide https://guides.emberjs.com/v2.12.0/components/handling-events/#toc_sending-actions
来源:https://stackoverflow.com/questions/29484490/pass-a-reference-of-the-clicked-dom-element-to-the-action-handler-in-ember