Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting watch on element inside ng-if

Let's say I have following view:

<div ng-if='some === "something"'>
   <input type="text" ng-model="foo.Bar"/>
</div>

In controller some is set:

foo.controller('fooFoo',
   function fooFoo($scope) {
      $scope.some = "something";
      $scope.$watch('foo.Bar',function (nVal, oVal) { etc...});
   }
);

Provided the input is inside a div with ng-if the watch doesn't work.

Why? Can I somehow make it work?

like image 903
Arkadiusz Kałkus Avatar asked Feb 24 '16 11:02

Arkadiusz Kałkus


3 Answers

You must create empty object of foo inside controller.

foo.controller('fooFoo',
   function fooFoo($scope) {
      $scope.foo = {};
      $scope.some = "something";
      $scope.$watch('foo.Bar',function (nVal, oVal) { etc...});
   }
);

recommended: you can use ng-change instead of $scope.$watch(); because $watch is a bad practice for angular app performance.

using ng-change (HTML):

<div ng-if='some === "something"'>
   <input type="text" ng-model="foo.Bar" ng-change="onChange()"/>
</div>

JavaScript:

foo.controller('fooFoo',
   function fooFoo($scope) {
      $scope.some = "something";

      $scope.onChange = function(){
          console.log($scope.foo.Bar);
     };
   }
);
like image 177
Nasser Ghiasi Avatar answered Nov 05 '22 19:11

Nasser Ghiasi


Use ng-change on input element instead of $watch in controller.

like image 2
Mahmoud Avatar answered Nov 05 '22 20:11

Mahmoud


I think problem is ng-if create its own scope. Then we have fooFoo scope (parent) and ng-if scope.

the property foo.Bar at first time (page init) is avaiable in both scope and point to the same place (foo.Bar property in fooFoo controller) because of inheritance. But after you change your input element (in ng-if scope), the foo.Bar in ng-if scope is pointed to its own scope property so foo.Bar in fooFoo controller is not getting changed.

If you use controllerAs i think it'll be resolved.

something like this:

<div ng-controller="fooFoo as ff">
    <div ng-if='ff.some === "something"'>
       <input type="text" ng-model="ff.foo.Bar"/>
    </div>
</div>

And you controller:

foo.controller('fooFoo',
   function fooFoo($scope) {
      var ff = this;
      ff.some = "something";
      $scope.$watch('ff.foo.Bar',function (nVal, oVal) { etc...});
   }
);
like image 2
Sherlocked Nguyen Avatar answered Nov 05 '22 20:11

Sherlocked Nguyen