Angular - ng-change not firing when ng-model is changed
Asked Answered
G

4

22

The input is the following:

<input type="text" ng-model="repair.test"  ng-change="action()" />

The action() is executed when I manually type and change the input. However if I change the repair.test value by some other function programmatically, it doesnt fire the ng-change's action. I have read the angular tutorial and it's probably the expected behavior.

https://docs.angularjs.org/api/ng/directive/ngChange

"The expression is not evaluated when the value change is coming from the model." <- I need this too. How can I fire an action in controller, when the model changes in any way? (typing in input or by any other function)

Thanks for the help.

Edit:

The model value is actually the form.$valid, which has it's own Form controller around it (I think), that is why I used the action function to try to pass the value to the parent controller. So $scope.$watch at the moment doesn't work, only when it is initialised.

Guzman answered 17/7, 2014 at 11:45 Comment(0)
T
29

ngChange is just for the input, if you want to listen the model do like this

$scope.$watch('repair.test', function(newvalue,oldvalue) {

            });
Tamayo answered 17/7, 2014 at 11:50 Comment(6)
Thanks, I have already tried this approach, the thing is, the value I actually need in controller is the form.$valid, which has its own Form controller. So basically I need to pass value from child controller to parent controller. That's the reason I used the action method, to try to pass value to controller. Any thoughts how I can do this?Guzman
I have reworked my code to use $scope.$watch, thank you.Guzman
ng-change should work for input type which is present in the main question. However i did not see any answer which tells why it did not work for ng-change? I too have the same issue. Thank youTimm
This really helped me to understand why $watch is used, thank you!Illumination
It is working if I put the value in new controller. Why its so???Hort
Check the values in the parameters, angular 1 did use the concept of "dirty checking" meaning that it can trigger this function even if the model is undefined (that's only a supposition as i haven't use angular 1 for years now)Tamayo
S
8

The ngChange expression is only evaluated when a change in the input value causes a new value to be committed to the model.

It will not be evaluated:

  • if the value returned from the $parsers transformation pipeline has not changed
  • if the input has continued to be invalid since the model will stay null
  • if the model is changed programmatically and not by a change to the input value

Try to create a watcher using $scope.$watch - $watch(watchExpression, listener, [objectEquality]);

Example

$scope.$watch('repair.test', function(newValue, oldValue) {
    // ...
});
Sn answered 12/9, 2016 at 13:55 Comment(0)
F
3

You can use a watcher-function in your controller

$scope.$watch('repair.test', function() {
    $scope.action();
});
Fingering answered 17/7, 2014 at 11:51 Comment(0)
C
0

Another solution would be to use a directive that watched the model for any changes instead of using ng-change.

app.directive('onModelChange', function($parse){
    return {
        restrict: "A",
        require: "?ngModel",
        link: function(scope, elem, attrs, ctrl) {
            scope.$watch(attrs['ngModel'], function (newValue, oldValue) {
                if (typeof(newValue) === "undefined" || newValue == oldValue) {
                    return;
                }
                var changeExpr = $parse(attrs['onModelChange']);
                if (changeExpr) {
                    changeExpr(scope);
                }
            });
        } 
    };
});

Then you would use it like so:

<input class="value" type="text" ng-model="myVar" on-model-change="doSomething(myVar)"/>
Clatter answered 22/10, 2018 at 17:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.