When you create two separate instances of ngModel
, they are both updated when the input changes.
The first instance is created by the <input>
itself and is assigned to 'myform'. This is the one that the error message within my-wrapper
is bound to.
The second instance is created by the my-wrapper
directive and has the validator attached to it.
If you check the console (for the plnkr below) and inspect the values being output by the validator when the input is changed, you will see that the ngModel
associated with the validator is different from the one associated with the form. However, both instances are being updated when the input changes.
Clear the console once the page has loaded and then observe the output when you change the first input.
http://plnkr.co/edit/nz6ODOVpn6lJlb055Svs?p=preview
What is the reason behind this?
Both ng-model
directives are passed the same string ('values.abc'), which is then evaluated against the scope to determine the object property they should watch and update - enabling two-way binding.
So, when you change the input, you are actually changing the value of scope.values.abc
through the input's ngModel
instance. This change is detected by the my-wrapper
ngModel
instance, as it is also watching the same object property and then proceeds to validate itself.
This issue cannot be resolved in this manner, as the ngModel
directive expects a string, not another ngModel
instance.
Solution
You could transfer the attributes from my-wrapper
to the input
during compilation:
app.directive("myWrapper", function(){
var templateFn = function(element, attrs){
return '<div ng-form="myform">'+
'<input type="text" name="myfield"/>'+
'<span>(inside directive) : isDuplicate:{{myform.myfield.$error.isDuplicate}}</span>'
'</div>';
}
return {
restrict :'E',
template : templateFn,
require: 'ngModel',
scope: true,
compile: function(element, attrs) {
var attr;
angular.forEach(element.find('input'), function(elem) {
elem = angular.element(elem)
for(attr in attrs.$attr) {
elem.attr(attrs.$attr[attr], attrs[attr]);
}
});
for(attr in attrs.$attr) {
element.removeAttr(attrs.$attr[attr]);
}
}
}
});
http://plnkr.co/edit/m2TV4BZKuyHz3JuLjHrY?p=preview