Angularjs Goodness – How to run Jquery scripts/apply styles after the table has been populated by ngRepeat

It is touch sometimes for JQuery and Angular to coexist esp. when there are external jquery scripts which are also manipulating the dom and Angular is reluctant to give the control over the DOM. We had a jquery script which was applying some styles on the the table, but with ngRepeat getting used in angular, those styles were not getting applied, as ngRepeat used to come later and manipulate the DOM its way.
Needed a way so that I can run the my jquery fuction only after the table has been completely reloaded, intially we went with $timeout() and in that  invoked the jquery function, but was very unreliable as you never know when angular has finished loading the table.
The $timeout internally calls apply() which will notify angularjs about DOM has changed externally and it has to run its digest cycle; but as mentioned above its unreliable, And I need to know
The way out of this is creating a directive which will listen to the $last property of ngRepeat , which represents the last element, and once the $last is invoked, go ahead and invoke the controller which can reload the custom jquery.
Here is the code which will explain it much better..
//Step1 -- ngRepeat directive to go through all the rows in the table
//emp.html - we see a snipped code which is conrolled by the empController
<div ng-controller="empController">
<table id="myTable" class="emp-table">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
<tbody ng-repeat="emp in employees">
<td class="empRow"> {{emp.name}} </td>
<td class="empRow"> {{emp.address}} </td>
</tbody>
</table>
</div>
//Step2 add a directive which will leverage the $last property of ngRepeat,
//listen to the when $last is called so that it can invoke a even which inturn can load the javascript
Application.Emp.directive('renderOnFinish',[function() {
return function(scope, element, attrs) {
if (scope.$last){
scope.$emit('event:table-loading-over');
}
}
}])
//Step3 - listen to even in the empController
//now we are using the timeout in this, reason is it calls the $apply method which will notify the angular about the dom change
$scope.$on('event:table-loading-over',function(event){
$timeout(function(){
loadCustomJS();
});
});
//Step4 - use the directive in the html
<div ng-controller="empController" >
<table id="myTable" class="emp-table" render-on-finish>
<td>.. </td>
</table>
</div>
view rawgistfile1.js hosted with ❤ by GitHub

Originally published in 2014

Comments

Popular posts from this blog

Apache Airflow Wait Between Tasks

Hibernate Interview Questions

Java Spring Interview Questions