Nate
Nate

Reputation: 7856

$watch not triggered the second time the value changes

Using AngularJS, I'm trying to $watch the scrollHeight of an element (hidden inside two tables) in a directive. The behavior is very strange; the first time the value changes, it triggers my function. The second time it doesn't and then it works for good...

The scrollHeight I'm watching is inside a double table:

<table> 
  <tbody>
    <tr>
      <td ng-click="show()" style="cursor:pointer">Show Row</td>
    </tr>
    <tr>
      <td>
        <table ng-show="showRow"> 
          <tbody>
            <tr>
              <td ng-click="showTD()" style="cursor:pointer">Show Cell</td>
            </tr> 
            <tr ng-show="showCell">
              <td id="tracker" tracker=""> Watch that</td>
            </tr>
          </tbody>
        </table>
      </td>
    </tr>
  </tbody>
</table>

And my directive to watch it:

myApp.directive('tracker', function() {
   return {
     compile : function(elem, attr, linker) {
       return function(scope, elm, attrs) {
          scope.$watch(function(){ return elm[0].scrollHeight }, function(){
             console.log(elm[0].scrollHeight);
          });
       };
     }
   }
});

I made a plunker to illustrate this behavior. If you open the console, you will see the following:

I need to detect whenever my 'Watch that' gets displayed but because of that, it is impossible.

Upvotes: 4

Views: 641

Answers (1)

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

You could use ng-if instead of ng-show that would to the trick, Adding and removing DOM will change run digest cycle, & after digest cycle watch gets called, then the height of element calculated properly.

Markup

<table ng-show="showRow"> 
   <tbody>
       <tr>
          <td ng-click="showTD()" style="cursor:pointer">Show Cell</td>
       </tr> 
       <tr ng-if="showCell">
          <td id="tracker" tracker=""> Watch that</td>
       </tr>
   </tbody>
</table>

Demo Plunkr

Upvotes: 1

Related Questions