I want to attach a DOM event to a directive element so as to update a scope property. Unfortunately, I can't find a "clean" way to do this. The only way I can get this to work now is to explicitly invoke $apply() inside the handler. This is bad practice, I know, but it also prevents me from sharing this code with native angular directives, such as with ng-click="myDOMEventHandler()" (because it triggers an $apply already in progress exception.
Is there a way to add a DOM event to a directive element so that changes to the scope are picked up, but without having to call $apply()?
Here is a simple example of what I mean. You can edit this Plunker as well).
angular.module('myApp', [])
.directive('myDirective', function ($compile) {
return {
link: function (scope, element) {
scope.keystrokes = 0;
var report = angular.element('<div ng-click="increment()">keystrokes: {{keystrokes}}</div>');
element.after(report);
$compile(report)(scope);
scope.increment = function () {
scope.keystrokes += 1;
scope.$apply();
};
element.on('keyup', scope.increment);
}
};
});
If you enter some text in the input, the counter increments. And if you click on the button, the counter also increments -- but if raises a $apply already in progress exception.
If you remove the scope.$apply(), then the exception goes away and the scope properties do change, but these changes are never displayed.