Reputation: 7856
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:
scrollHeight
(29)scrollHeight
value) and the $watch
gets triggered and displays the updated value (0) - This is correct, the element's scrollHeight
is 0scrollHeight
has changed (29)) but the $watch doesn't trigger the function!?! - It's only when you click again on 'Show cell' that it gets triggered and display the wrong value of 29!I need to detect whenever my 'Watch that' gets displayed but because of that, it is impossible.
Upvotes: 4
Views: 641
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>
Upvotes: 1