ember-on-modifier
An implementation of the {{on}}
element modifier shown in the Modifiers RFC
#353. Heavily inspired by
@ember/render-modifiers
.
Installation
ember install ember-on-modifier
Compatibility
- Ember.js v2.18 or above
- ember-cli v2.13 or above
Usage
<button {{on "click" this.onClick}}>
Click me baby, one more time!
</button>
import Component from '@ember/component';
import { action } from '@ember-decorators/object';
export default class BritneySpearsComponent extends Component {
@action
onClick(event: MouseEvent) {
console.log('I must confess, I still believe.');
}
}
The @action
decorator is used to bind the onClick
method to the
component instance. Alternatively, you can use the {{action}}
or {{bind}}
helper in the template.
This is essentially equivalent to:
didInsertElement() {
super.didInsertElement();
const button = this.element.querySelector('button');
button.addEventListener('click', this.onClick);
}
In addition to the above {{on}}
will properly tear down the event listener,
when the element is removed from the DOM. It will also re-register the event
listener, if any of the passed parameters change.
Listening to Multiple Events
You can use the {{on}}
modifier multiple times on the same element, even for
the same event.
<button
{{on "click" this.onClick}}
{{on "click" this.anotherOnClick}}
{{on "mouseover" this.onMouseEnter}}
>
Click me baby, one more time!
</button>
Event Options
All named parameters will be passed through to
addEventListener
as the third parameter, the options hash.
<div {{on "scroll" this.onScroll passive=true}}>
Lorem Ipsum ...
</div>
This is essentially equivalent to:
didInsertElement() {
super.didInsertElement();
const div = this.element.querySelector('div');
div.addEventListener('scroll', this.onScroll, { passive: true });
}
Currying / Partial Application
If you want to curry the function call / partially apply arguments, you can do
so using the {{action}}
or {{bind}}
helper:
{{#each this.users as |user|}}
<button {{on "click" (action this.deleteUser user)}}>
Delete {{user.name}}
</button>
{{/each}}
import Component from '@ember/component';
import { action } from '@ember-decorators/object';
interface User {
name: string;
}
export default class UserListComponent extends Component {
users: User[] = [{ name: 'Tom Dale' }, { name: 'Yehuda Katz' }];
@action
deleteUser(user: User, event: MouseEvent) {
event.preventDefault();
this.users.removeObject(user);
}
}
preventDefault
This addon ships a prevent-default
template helper, that you can use like
this:
<a href="/" {{on "click" (prevent-default this.someAction)}}>Click me</a>
<a href="/" {{on "click" this.someAction}} {{on "click" (prevent-default)}}>Click me</a>
This is effectively the same as calling event.preventDefault()
in your event
handler or using the {{action}}
modifier
like this:
<a href="/" {{action this.someAction preventDefault=true}}>Click me</a>