str str - 5 months ago 21
AngularJS Question

Directives with non-isolated scope and event handlers in Angular

I'm creating a simple directive to add a clear button to

input
fields.

angular.module('module').directive('strClearable', ($compile) => ({
restrict: 'A',
require: 'ngModel',
link: (scope, el, attrs, ngModel) => {
const template = $compile('<span ng-click="reset()">&times</span>')(scope);
el.after(template);

scope.reset = () => {
ngModel.$setViewValue('test');
ngModel.$render();
};
},
})
);

<input type="text" ng-model="something" str-clearable>


This works flawlessly as long as it is only used once per page. If there are several
input
s, each with the directive applied, clearing will not work properly anymore. It always just clears the last
input
of the page. This seems to be caused by the
scope.reset
method that is overwritten each time the directive is applied to an
input
field. As a result,
ngModel
will always point the to last
input
model.

How can I rewrite the directive to work for each
input
instead without adding an isolated scope?

Answer

You can do it this way:

angular.module('module').directive('strClearable', () => ({
        restrict: 'A',
        require: 'ngModel',
        link: (scope, el, attrs, ngModel) => {
            var btn = angular.element('<span>&times</span>');
            el.after(btn);

            btn.on('click', function() {
              ngModel.$setViewValue('');
              ngModel.$render();
              el[0].focus();
            });

        },
    })
);