0

I have a textarea tag with jquery.nicescroll pluggin and ng-model attached to it.

<textarea id="paper" ng-model="paper"></textarea>

In my code I apply a $watch on this ng-model variable.

$scope.$watch("paper", onTextChange);

Everything is good except that onTextChange is fired not only when I type something, but when I click away from textareaб and also when I switch to another tab.

How can I prevent it so that onTextChange is fired only when the text is changed, meaning when I type in something or delete chars?

Demo with instructions: plunker

kaytrance
  • 2,657
  • 4
  • 30
  • 49
  • you use watch to listen to changes to paper, not to event onTextChange.So when paper change, it executes your function. – changtung Jan 19 '15 at 10:19
  • nope, by that statement I am telling angular to watch for **paper** variable changes (in $scope) and fire up my **onTextChanged()** function if that variable is changed. And because it is bound to my textarea via ng-model, this event should be fired when I type something in textarea. Which IS fired, but not only when I type in something, but also when I only scroll down/up and click away. Which is strange. – kaytrance Jan 19 '15 at 10:23

2 Answers2

2

here's a fix:

http://plnkr.co/edit/kycmUrthYU38Ukdz0jJG?p=preview

setTimeout( 
function() {
    $scope.$watch("paper", function(newtext, oldtext) {
      if (newtext !== oldtext) {
        onTextChange();
      }
    });
  }, 100)

So the issue is that watch fires the function whenever angularjs tells the app to digest. What you did was tell it to call the 'change' function EVERY time, when you should have passed in a checker function to check the change happened. It's about 'watching', not about 'watching for changes' - the function argument is supposed to see if you need to do something.

Extra note:

AngularJS sets up watchers for all kinds of things on various elements - here's a bit more info. I believe the blur corresponds to ng-touched which triggers the digest What gets added to $scope.$$watchers by default in Angular? And what triggers $digests?

Community
  • 1
  • 1
Peter Ashwell
  • 4,292
  • 2
  • 18
  • 22
  • I think if you remove setTimeout, onTextChange method will get called on load event as theextbox is initially empty and there may be little delay in text populated in textbox.. – Ved Jan 19 '15 at 11:15
2

It is a bad idea to use setTimeout. Instead, you could use ng-model-options="{ getterSetter: true }" and write a method to get/set the value (Modified get/set Plunk) and handle the text change condition within this method.

Coder X
  • 4,542
  • 2
  • 16
  • 9