Modifying AngularJS form field validation attributes asynchronously

196 Views Asked by At

I have a situation similar to this question. My unique twist is that I receive my "dynamic" information asynchronously (via a webservice call) at some point after the page has completed its initial render/bind. So, my directive's flow is like this:

** UPDATE: Complete repro here: http://plnkr.co/edit/TIVbhGFMAQpUaMxKp9Dc?p=info

 Markup: <input dynValidate />
 Directive:

 app.directive('dynValidate',function($compile,$parse) {
      restrict: 'A', require: 'ngModel', replace: false, terminal: true,
      link: function (scope, elem, attr, ctrl) {
        var validatorKey = elem.attr('ng-model') + 'Validation';
        var installValidators = function () {
                // ...add some ng-validation attributes     
                // (omitted for brevity, but does something like elem.attr('ng-minlength','5')
                // based on metadata in the bound model
                elem.removeAttr('dynValidate'); // Remove my own directive
                $compile(elem)(scope); // recompile to incorporate new ng directives
            }
        };
        // watch for the validation metadata to arrive asynchronously
        scope.$watch(validatorKey, function() {
            installValidators(attr, ctrl);
        });
      }
  });

This sort-of works: my directive attribute is replaced by some angular validation directives and validation is functioning properly at the level of this element. The problem is that the async recompile seems to have caused the parent ng-form to lose track of the element. Specifically, the form.fieldName.$isDirty will never be set to true when the input is changed. It makes sense, since I have essentially removed the original element and replaced it with a different one, but I'm wondering if there's any mechanism which will allow me to tell the parent form that this has happened, and that it should hook up its $error/$dirty mechanism at the form level.

Thanks!

1

There are 1 best solutions below

4
On

I'd suggest getting the ngModel controller of the re-compiled <input> and registering it with the form's ngForm controller using $addControl.