Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$watch is firing only once inside directive

Tags:

angularjs

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.

like image 524
Nitya Avatar asked Apr 17 '15 19:04

Nitya


1 Answers

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;
});

Working Plunker

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
    });
}

Working Plunker

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.

like image 107
Michael Benford Avatar answered Oct 01 '22 22:10

Michael Benford