0

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!

Community
  • 1
  • 1
jlew
  • 10,491
  • 1
  • 35
  • 58

1 Answers1

0

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

hon2a
  • 7,006
  • 5
  • 41
  • 55
  • Interesting idea, is there a way to get at the form controller from inside the directive? – jlew Nov 24 '14 at 19:02
  • [Require it](https://docs.angularjs.org/api/ng/service/$compile) just like you require `ngModel` controller (prefix name with `^` to get directive controller from ancestor element). – hon2a Nov 24 '14 at 20:04
  • Ah cool, the require worked but it does not seem to affect the behavior in plunkr. – jlew Nov 24 '14 at 20:11
  • Have you tried to `$removeControl` first before recompilation? Or maybe not putting `ngModel` on the input in the first place and adding it only when adding the rest of the attributes? Also, you must get the `ngModel` controller **of your newly compiled element**, not use the original one you `require`d. To do that, use `compiledElement.controller('ngModel')`. – hon2a Nov 24 '14 at 20:22