2

When binding to to ngModel, if you have an object:

scope.someObj = { 
    prop: 10, 
    prop2: [20, 30], 
    subObj: {
        prop: 40
    } 
}

and you attach it to some input fields like so:

<input type="number" ng-model="someObj.prop" />
<input type="number" ng-model="someObj.prop2[0]" />
<input type="number" ng-model="someObj.prop2[1]" />
<input type="number" ng-model="someObj.subObj.prop" />

And put an event listener to the $render trigger of each of them, like so:

ngModel.$render = function() {console.log("Hello");};

The $render will only fire then the first input is edited, but never when the others are. Basically, the $render doesn't trigger on models bound to anything deeper than one level.

Is there a way to force it to do so?

Swader
  • 11,387
  • 14
  • 50
  • 84
  • This is odd. How do you add the `$render()` method? I presume that you've a custom directive, right? Could you provide a live code example with plunker? – pkozlowski.opensource Jun 30 '13 at 14:51
  • Yes, it all happens in a custom directive. It's all part of this discussion really: https://github.com/angular-ui/angular-ui/issues/252 Working on a plunker now, will update OP when done. – Swader Jun 30 '13 at 14:53
  • This is why (and I have no idea why they are executing it inside the watcher function and not the callback): https://github.com/angular/angular.js/blob/a22596c925a41c6f9b78cb21e18894987bbbc84b/src/ng/directive/input.js#L1084 – ProLoser Jun 30 '13 at 21:14
  • For some reason, it actually works when I test it in this plunker: http://plnkr.co/edit/8A3K1Jxjs7q03FYMXkQA?p=preview testing further... – Swader Jun 30 '13 at 23:12

2 Answers2

2

I used $scope.$watch to monitor it.

<input ng-model="myInputs.a">
<input ng-model="myInputs.b">

var obj = {};

$scope.$watch('myInputs', function(){
   // do whatever here ....
   // you can assign variables to myInputs
   obj.x = myInputs.a;

   }, true);

The key here is to add the last parameter true, so it deep monitors your object.

Lance
  • 865
  • 8
  • 19
  • Watch helps, as evident by this: https://github.com/angular-ui/ui-slider/blob/master/src/slider.js#L48 Can you update your code to use attributes.ngModel instead of 'someObj' so I can mark it as correct? – Swader Jul 03 '13 at 00:00
  • I don't think watching attributes.ngModel will work. You either need to bind myInput in your scope and watch it or watch a function that returns myInput. See http://stackoverflow.com/questions/14693052/watch-ngmodel-from-inside-directive-using-isolate-scope – yoonchee Jan 03 '15 at 02:10
  • yoonchee - usually you would watch the models inside a controller. – Lance Jan 04 '15 at 00:03
0

Your solution goes like this:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.0.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js" data-semver="1.0.7"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <input type="number" ng-model="someObj.prop" />
    <input type="number" ng-model="someObj.prop2[0]" />
    <input type="number" ng-model="someObj.prop2[1]" />
    <input type="number" ng-model="someObj.subObj.prop" />
  </body>

</html>
Heinrich
  • 313
  • 2
  • 13