Search code examples
angularjsangularjs-directiveangularjs-scope

Angular error: Multiple directives asking for new/isolated scope


I have these two directives:

app.directive('autofocus', function ($timeout) {
  return {
    scope: {
      trigger: '=autofocus'
    },
    replace: false,
    link: function (scope, element) {
      scope.$watch('trigger',
        function (value) {
          if (value) {
            $timeout(function () {
              element[0].focus();
            });
          }
        }
      );
    }
  };
});

app.directive('checkCustomerName', function(Customer) {
  return {
    require: 'ngModel',
    scope: {
      value: '=ngModel'
    },
    link: function(scope, elm, attrs, model) {
      var CUSTOMERNAME_REGEXP = /^([ \u00c0-\u01ffa-zA-Z'\-])+$/;
      var retval;
      model.$parsers.unshift(function(viewValue) {
        if (CUSTOMERNAME_REGEXP.test(viewValue)) {
          var current = attrs.customerId;
          var exists = Customer.findByName(viewValue);
          if (exists && exists !== current) { // customer name exists already
            model.$setValidity('taken', false);
            model.$setValidity('invalid', true);
          } else { // customer name does not exist
            model.$setValidity('taken', true);
            model.$setValidity('invalid', true);
            retval = viewValue;
          }
        } else { // customer name is not valid
          model.$setValidity('taken', true);
          model.$setValidity('invalid', false);
        }
        return retval;
      });
      elm.bind('blur', function() {
        if (model.$viewValue) { // capitalize all words in value
          model.$viewValue = capitalizeAllWords(model.$viewValue);
          model.$render();
        }
      });
    }
  };
});

They work smootly when used separatedly, but, when used on the same element, I get:

Multiple directives [autofocus, checkCustomerName] asking for new/isolated scope on:
<input type="text" autofocus="true" check-customer-name>

How can I let them working togheter?
(Sorry, I did not dig into ng-directives logic, yet... :-().


Solution

  • Just remove the isolated scope of one of your directives and watch the attribute instead.

    F.e.

    app.directive('autofocus', function ($timeout) {
      return {
        replace: false,
        link: function (scope, element, attr) {
          scope.$watch(attr.autofocus,
            function (value) {
              if (value) {
                $timeout(function () {
                  element[0].focus();
                });
              }
            }
          );
        }
      };
    });