42

I've got an AngularJS attribute directive, and I would like to take an action any time its parent input's value changes. Right now I'm doing it with jQuery:

angular.module("myDirective", []) .directive("myDirective", function() { return { restrict: "A", scope: { myDirective: "=myDirective" }, link: function(scope, element, attrs) { element.keypress(function() { // do stuff }); } }; }); 

Is there a way to do this without jQuery? I'm finding the keyPress event isn't doing exactly what I want it to, and while I'm sure I'll come up with a solution, I get a little nervous when I resort to using jQuery in an Angular project.

So what's the Angular way to do this?

3 Answers 3

67

There's a great example in the AngularJS docs.

It's very well commented and should get you pointed in the right direction.

A simple example, maybe more so what you're looking for is below:

jsfiddle


HTML

<div ng-app="myDirective" ng-controller="x"> <input type="text" ng-model="test" my-directive> </div> 

JavaScript

angular.module('myDirective', []) .directive('myDirective', function () { return { restrict: 'A', link: function (scope, element, attrs) { scope.$watch(attrs.ngModel, function (v) { console.log('value changed, new value is: ' + v); }); } }; }); function x($scope) { $scope.test = 'value here'; } 


Edit: Same thing, doesn't require ngModel jsfiddle:

JavaScript

angular.module('myDirective', []) .directive('myDirective', function () { return { restrict: 'A', scope: { myDirective: '=' }, link: function (scope, element, attrs) { // set the initial value of the textbox element.val(scope.myDirective); element.data('old-value', scope.myDirective); // detect outside changes and update our input scope.$watch('myDirective', function (val) { element.val(scope.myDirective); }); // on blur, update the value in scope element.bind('propertychange keyup paste', function (blurEvent) { if (element.data('old-value') != element.val()) { console.log('value changed, new value is: ' + element.val()); scope.$apply(function () { scope.myDirective = element.val(); element.data('old-value', element.val()); }); } }); } }; }); function x($scope) { $scope.test = 'value here'; } 
Sign up to request clarification or add additional context in comments.

11 Comments

That could work. Any idea how to do it without requiring a model? I'd like to only add the directive.
If you want the directive to serve as ngModel, you can use isolate scope w/ a two-way binding, shown here: jsfiddle.net/langdonx/djtQR
I'm already using the directive, I'm afraid, but great suggestion.
What you have there is great. If I could do that without requiring the model, it would be perfect. It's not a deal-breaker, but I'd love to not require the model, since I'm not actually using it for anything. Marking this as the answer, since it's pretty much what I want, but if you have any ideas on how I can drop the model, I'd be interested. Thank you very much for your help.
What do mean already using the directive? I was suggesting that you modify your myDirective to act like the ngModelBlur directive in my example, which that doesn't require ngModel.
|
12

Since this must have an input element as a parent, you could just use

<input type="text" ng-model="foo" ng-change="myOnChangeFunction()"> 

Alternatively, you could use the ngModelController and add a function to $formatters, which executes functions on input change. See http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController

.directive("myDirective", function() { return { restrict: 'A', require: 'ngModel', link: function(scope, element, attr, ngModel) { ngModel.$formatters.push(function(value) { // Do stuff here, and return the formatted value. }); }; }; 

1 Comment

$formatters fire only on page load. $parsers fires on input change.
0

To watch out the runtime changes in value of a custom directive, use $observe method of attrs object, instead of putting $watch inside a custom directive. Here is the documentation for the same ... $observe docs

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.