Reputation: 163
I am new to angular js, so Please some one help me out.I have my template here:
<form ng-model="signup" form-valid>
<input type="text" name="username" ng-model="signup.username">{{signup}}
</form>
And my directive is like this:
app.directive("formValid",function(){
return {
restrict:"A",
require:"ngModel",
link:function(scope,element,attrs){
scope.$watch(attrs.ngModel,function(newValue){
if(newValue){
console.log(newValue);
}
});
}
}});
When ever I am entering some value into text box the model is changing and accordingly "$watch" should fired.But in here "$watch" is fired only once when for the first time I enter any value in to text box.Thanks in advance.
Upvotes: 7
Views: 4505
Reputation: 14104
When you use ngModelController
, the standard way for watching changes on the model is by creating a formatter
:
link: function(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$formatters.push(function(value) {
// Do something with value
return value;
});
}
Keep in mind that formatters are only triggered when the model is changed directly. If the change comes from the UI (i.e. the user changes something), then parsers are triggered instead. So you may need to do this as well:
ngModelCtrl.$parsers.push(function(value) {
// Do something with value
return value;
});
I suggest that you read ngModelController documentation so you understand exactly how those pipelines work.
But if all you want to do is get notified when the model changes (you don't want or need to neither format nor parse anything), then you can do something simpler:
scope: { model: '=ngModel' },
link: function(scope) {
scope.$watch('model', function(value) {
// Do something with value
});
}
But given your directive's name, formValid
, I think that using ngModelController is the correct approach.
UPDATE
It's worth mentioning that ngModelController has arguably one shortcoming: it doesn't work very well with "reference" types (e.g. arrays, objects). More details on that can be found here.
Upvotes: 3
Reputation: 1579
One solution would be to use ngModel like in the example below.
app.directive("formValid",function(){
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
scope.$watch(function () {
return ngModel.$modelValue;
}, function(newValue) {
console.log(newValue);
});
}
}
});
Edit: The quickest solution would be to follow the comment by Blackhole and update your watch to a deep watch by adding true
. This is because you are watching the signup
attribute but the model value username
is a property of signup. The deep watch will serve to watch the properties.
Using ngModel
directly rather than via the attrs
, or using formatters or parsers (as detailed in Michaels answer is a better solution in my view).
Upvotes: -1