angularjs - ng-class strange behaviour after after $compile -


i have made following directive:

(function () {     'use strict';      angular         .module('app.widgets')         .directive('zzforminput', forminput);      function forminput($compile) {         // usage:         //     <div zz-forminput></div>          function setupdom(element) {             var input = element.queryselector("input, textarea, select");             var type = input.getattribute("type");             var name = input.getattribute("name");             if (type !== "checkbox" && type !== "radio") {                 input.classlist.add("form-control");             }             var label = element.queryselector("label");             label.classlist.add("control-label");              element.classlist.add("form-group");             return name;         }          function addngclass(form, element, name, $compile, scope) {             var isexistingngclass = element[0].attributes["data-ng-class"] || element[0].attributes["ng-class"];             if (!isexistingngclass) {                 var ngclass = "{'has-error':" + form.$name + "." + name + ".$invalid && " +                                 "(" + form.$name + "." + name + ".$dirty || vm.submit), " +                                 "'has-success':" + form.$name + "." + name + ".$valid && " +                                 form.$name + "." + name + ".$dirty}";                 element.attr("data-ng-class", ngclass);                 $compile(element)(scope);             }         }          function link($compile) {             return function (scope, element, attrs, form) {                 var name = setupdom(element[0]);                  addngclass(form, element, name, $compile, scope);             }         }          return {             restrict: 'a',             require: '^form',             link: link($compile)         }     }  }()); 

i using directive as:

<div zz-forminput>    <label for="firstname" class="col-md-4">first name*</label>    <div class="col-md-8">        <input type="text" name="firstname" id="firstname" data-ng-model="vm.userdetails.firstname" required data-ng-maxlength="100">    </div> </div> 

angular compiles markup successfully. when enter text in input field, has-success not added div. when clear textbox, has-success class appied div. now, when enter text in input, has-success applied div.

please provide me solution issue

the reason seeing weird behavior because of how handle contents of element hosts directive.

what happens contents, including ng-model directive on input, compiled twice: once when angular goes on dom (in compile phase), , once when manually invoke $compile service (in linking phase of directive). causes ng-model directive register twice - under same name - parent form controller, , long story short, causes weirdness.

the proper way deal contents using transclude function, provided link function of directive.

transclude: true, link: function(scope, element, attrs, ctrls, transclude){    transclude(scope, function(clone){      element.append(clone); // clone clone of contents, prebound scope    } } 

or, simply, <div ng-transclude></div> via template, since don't need special there

transclude: true, template: '<div ng-transclude></div>` 

but don't need of this, since directive puts classes on contents , applies classes itself, trying ng-class, requires use $compile. instead of doing this, $watch changes , apply class directly:

link: function(scope, element, attrs, formctrl){   var inputname = setupdom(element[0]);    scope.$watch(function(){     return formctrl[inputname].$valid && formctrl[inputname].$dirty;   }, function(v){     if (v) element.addclass("has-success");     else element.removeclass("has-success");   });    scope.$watch(function(){     return formctrl[inputname].$invalid &&             (formctrl[inputname].$dirty || formctrl.$submitted);   }, function(v){     if (v) element.addclass("has-error");     else element.removeclass("has-error");   }) } 

and there no need $compile or transclude

plunker


Comments

Popular posts from this blog

c++ - Delete matches in OpenCV (Keypoints and descriptors) -

java - Could not locate OpenAL library -

sorting - opencl Bitonic sort with 64 bits keys -