The ngOn
directive adds an event listener to a DOM element via
angular.element().on(), and evaluates an expression when the event is
fired.
ngOn
allows adding listeners for arbitrary events by including
the event name in the attribute, e.g. ng-on-drop="onDrop()"
executes the 'onDrop()' expression
when the drop
event is fired.
AngularJS provides specific directives for many events, such as ngClick
, so in most
cases it is not necessary to use ngOn
. However, AngularJS does not support all events
(e.g. the drop
event in the example above), and new events might be introduced in later DOM
standards.
Another use-case for ngOn
is listening to
custom events
fired by
custom elements.
Since HTML attributes are case-insensitive, camelCase properties like myEvent
must be escaped.
AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so
myEvent
must be written as ng-on-my_event="expression"
.
<ANY ng-on-eventname="expression">
</ANY>
or with uppercase letters in property (e.g. "eventName"):
<ANY ng-on-event_name="expression">
</ANY>
angular.module('exampleNgOn', [])
.component('main', {
templateUrl: 'main.html',
controller: function() {
this.clickCount = 0;
this.mouseoverCount = 0;
this.loadingState = 0;
}
});
<div>
This is equivalent to `ngClick` and `ngMouseover`:<br>
<button
ng-on-click="$ctrl.clickCount = $ctrl.clickCount + 1"
ng-on-mouseover="$ctrl.mouseoverCount = $ctrl.mouseoverCount + 1">Click or mouseover</button><br>
clickCount: {{$ctrl.clickCount}}<br>
mouseover: {{$ctrl.mouseoverCount}}
<hr>
For the `error` and `load` event on images no built-in AngularJS directives exist:<br>
<img src="thisimagedoesnotexist.png" ng-on-error="$ctrl.loadingState = -1" ng-on-load="$ctrl.loadingState = 1"><br>
<div ng-switch="$ctrl.loadingState">
<span ng-switch-when="0">Image is loading</span>
<span ng-switch-when="-1">Image load error</span>
<span ng-switch-when="1">Image loaded successfully</span>
</div>
</div>
<main></main>
angular.module('exampleNgOn', [])
.component('main', {
templateUrl: 'main.html',
controller: function() {
this.eventLog = '';
this.listener = function($event) {
this.eventLog = 'Event with type "' + $event.type + '" fired at ' + $event.detail;
};
}
})
.component('childComponent', {
templateUrl: 'child.html',
controller: function($element) {
this.fireEvent = function() {
var event = new CustomEvent('customtype', { detail: new Date()});
$element[0].dispatchEvent(event);
};
}
});
<child-component ng-on-customtype="$ctrl.listener($event)"></child-component><br>
<span>Event log: {{$ctrl.eventLog}}</span>
<button ng-click="$ctrl.fireEvent()">Fire custom event</button>
<main></main>