iftheshoefritz
iftheshoefritz

Reputation: 6129

Directive calls setValidity(false) on field but field validity never changes according to view

With reference to this plunk: http://plnkr.co/edit/GzC9ufa1WJmKQ6Ad15v9?p=preview

I have a directive that runs a test and then calls $scope.form['myfield'].setValidity() with the result. However this does not reflect in the view or the controller.

Simple example that will always set false:

app.directive('myDirective', function() {
  return {
    link: function(scope, elem, attrs) {
      elem.on('blur change', function() {
        console.log("start valid:" + scope.form[attrs.name].$valid);
        scope.form[attrs.name].$setValidity('myfield', false);
        console.log("end valid:" + scope.form[attrs.name].$valid);
      });
    }
  };
});

in my view:

<input type="text" ng-model="myModel" name="myfield" my-directive/>

Console logging confirms that when the event in the directive first fires, the field is valid, then after setValidity it becomes false. On subsequent events it is false before the event fires. However, when I print out {{form['myfield'].$valid}} in the view, it remains true regardless.

I guess this is might be a timing thing, that by the time setValidity(false) runs in the directive, the view has already checked. How do I fix this?

Upvotes: 0

Views: 351

Answers (1)

Michael Kang
Michael Kang

Reputation: 52847

Wrap your code in an $apply to trigger a digest:

app.directive('myDirective', function() {
  return {
    link: function(scope, elem, attrs) {
      elem.on('blur change', function() {
        console.log("start valid:" + scope.form[attrs.name].$valid);
        scope.$apply(function() {
            scope.form[attrs.name].$setValidity('myfield', false);
            console.log("end valid:" + scope.form[attrs.name].$valid);
        });
      });
    }
  };
});

Upvotes: 1

Related Questions