I use ctrl.$setValidity within one of my directives to invalidate a form. However, there is a method residing elsewhere which could remove this element from the DOM under a different set of conditions. What happens when I invalidate the form with $setValidity and then remove the offending element is that the form remains invalid, while what I would like it to do is to recalculate its validity based on its new Inputfield set.
Please note that I am not simply looking for a ctrl.$setValidity true, (other input fields in the form may or may not be valid), I simply want the form to recalculate.
Below is the directive code:
app.directive('dir', function() {
return {
restrict: 'C',
require: "ngModel",
link: function(scope, element, attrs, ctrl) {
someValue = scope.someValue;
someField = element.find(".some-class");
monitorField = function(newValue, oldValue){
console.log("whee");
scope.someFunction(newValue);
if(newValue =="Invalidate NOW!"){
ctrl.$setValidity('someClass', false);
} else if (oldValue == "Invalidate NOW!"){
angular.element(document.querySelector('.some-class')).remove();
} else {
ctrl.$setValidity('someClass', true);
}
}
scope.$watch("someValue", monitorField, true);
}
}
});
Which operates on:
<FORM class="dir" ng-model="someValue">
<INPUT type="text" class="some-class" ng-model="someValue"/>
<INPUT type="text" class="some-other-class"/>
</FORM>
(Yes it is a somewhat contrived example).
The problem is reproduced here: http://jsfiddle.net/kTuAY/
In my actual code, I populate the input fields based on an array of objects, which gets populated via Service, and remove elements via array.splice. The example given in the jsfiddle is merely there for simplicity.
Another interesting condition of failure can be seen in this fiddle:
Specifically, if one of the inputs depends on non collision of value with the other, and is thusly invalidated, whereafter the other fields value is changed, validity remains incorrect.
Temporary not quite functioning fiddle while I go to work:
Thanks!
The way I ended up solving this was:
ng-repeatedover..val(), and then call$compileon the inner fields to retrigger the inner watch expressionctrl.$setValidityfrom the inner directive:The good:
The bad:
$digest‘s is doubledI’ll put together a code example just as soon as I sanitize the code.