str
str

Reputation: 44959

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 inputs, 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?

Upvotes: 0

Views: 226

Answers (1)

Alexander Kravets
Alexander Kravets

Reputation: 4385

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();
            });

        },
    })
);

Upvotes: 1

Related Questions