Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Attribute directive input value change

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?

like image 347
Mike Pateras Avatar asked Apr 30 '13 20:04

Mike Pateras


2 Answers

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.       });   }; }; 
like image 41
Jmr Avatar answered Sep 16 '22 18:09

Jmr


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'; } 
like image 180
Langdon Avatar answered Sep 16 '22 18:09

Langdon