Guest User

Untitled

a guest
Apr 20th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.80 KB | None | 0 0
  1. <!doctype html>
  2. <html ng-app="Demo">
  3. <head>
  4. <meta charset="utf-8" />
  5.  
  6. <title>
  7. Hooking Into The ngRepeat Completion Event In AngularJS
  8. </title>
  9.  
  10. <style type="text/css">
  11.  
  12. a[ ng-click ] {
  13. cursor: pointer ;
  14. text-decoration: underline ;
  15. }
  16.  
  17. </style>
  18. </head>
  19. <body ng-controller="AppController">
  20.  
  21. <h1>
  22. Hooking Into The ngRepeat Completion Event In AngularJS
  23. </h1>
  24.  
  25.  
  26. <h3>
  27. Friends
  28. </h3>
  29.  
  30. <ul>
  31. <!--
  32. When the ngRepeat finishes its first round of rendering,
  33. we're going to invoke the doSomething() callback.
  34. -->
  35. <li
  36. ng-repeat="friend in friends"
  37. repeat-complete="doSomething( $index )">
  38.  
  39. {{ friend.name }}
  40.  
  41. </li>
  42. </ul>
  43.  
  44. <p>
  45. <a ng-click="addFriend()">Add Friend</a>
  46. -
  47. <em>This will NOT trigger any more "complete" events</em>.
  48. </p>
  49.  
  50.  
  51. <h3>
  52. Enemies
  53. </h3>
  54.  
  55. <ul>
  56. <!--
  57. When the ngRepeat finishes its first round of rendering,
  58. we're going to invoke the doSomething() callback.
  59. -->
  60. <li
  61. ng-repeat="enemy in enemies"
  62. repeat-complete="doSomething( $index )">
  63.  
  64. {{ enemy.name }}
  65.  
  66. </li>
  67. </ul>
  68.  
  69. <p>
  70. <a ng-click="addEnemy()">Add Enemy</a>
  71. -
  72. <em>This WILL trigger one more "complete" event</em>.
  73. </p>
  74.  
  75.  
  76. <!-- Load scripts. -->
  77. <script type="text/javascript" src="../../vendor/jquery/jquery-2.0.3.min.js"></script>
  78. <script type="text/javascript" src="../../vendor/angularjs/angular-1.2.min.js"></script>
  79. <script type="text/javascript">
  80.  
  81. // Create an application module for our demo.
  82. var app = angular.module( "Demo", [] );
  83.  
  84.  
  85. // -------------------------------------------------- //
  86. // -------------------------------------------------- //
  87.  
  88.  
  89. // I control the root of the application.
  90. app.controller(
  91. "AppController",
  92. function( $scope ) {
  93.  
  94. // Define the collection of friends to render.
  95. $scope.friends = [
  96. {
  97. name: "Sarah"
  98. },
  99. {
  100. name: "Joanna"
  101. },
  102. {
  103. name: "Tricia"
  104. }
  105. ];
  106.  
  107. // Define the collection of enemies to render. This
  108. // collection will start out empty in order to demonstrate
  109. // that this approach requires at least ONE element to
  110. // render.
  111. $scope.enemies = [];
  112.  
  113.  
  114. // ---
  115. // PUBLIC METHODS.
  116. // ---
  117.  
  118.  
  119. // I add a new enemty to the collection.
  120. $scope.addEnemy = function() {
  121.  
  122. $scope.enemies.push({
  123. name: "Banana"
  124. });
  125.  
  126. }
  127.  
  128.  
  129. // I add a new friend to the collection.
  130. $scope.addFriend = function() {
  131.  
  132. $scope.friends.push({
  133. name: "Anna"
  134. });
  135.  
  136. }
  137.  
  138.  
  139. // I am the callback handler for the ngRepeat completion.
  140. $scope.doSomething = function( index ) {
  141.  
  142. console.log( "ngRepeat completed (" + index + ")!" );
  143.  
  144. };
  145.  
  146. }
  147. );
  148.  
  149.  
  150. // -------------------------------------------------- //
  151. // -------------------------------------------------- //
  152.  
  153.  
  154. // I invoke the given expression when associated ngRepeat loop
  155. // has finished its first round of rendering.
  156. app.directive(
  157. "repeatComplete",
  158. function( $rootScope ) {
  159.  
  160. // Because we can have multiple ng-repeat directives in
  161. // the same container, we need a way to differentiate
  162. // the different sets of elements. We'll add a unique ID
  163. // to each set.
  164. var uuid = 0;
  165.  
  166.  
  167. // I compile the DOM node before it is linked by the
  168. // ng-repeat directive.
  169. function compile( tElement, tAttributes ) {
  170.  
  171. // Get the unique ID that we'll be using for this
  172. // particular instance of the directive.
  173. var id = ++uuid;
  174.  
  175. // Add the unique ID so we know how to query for
  176. // DOM elements during the digests.
  177. tElement.attr( "repeat-complete-id", id );
  178.  
  179. // Since this directive doesn't have a linking phase,
  180. // remove it from the DOM node.
  181. tElement.removeAttr( "repeat-complete" );
  182.  
  183. // Keep track of the expression we're going to
  184. // invoke once the ng-repeat has finished
  185. // rendering.
  186. var completeExpression = tAttributes.repeatComplete;
  187.  
  188. // Get the element that contains the list. We'll
  189. // use this element as the launch point for our
  190. // DOM search query.
  191. var parent = tElement.parent();
  192.  
  193. // Get the scope associated with the parent - we
  194. // want to get as close to the ngRepeat so that our
  195. // watcher will automatically unbind as soon as the
  196. // parent scope is destroyed.
  197. var parentScope = ( parent.scope() || $rootScope );
  198.  
  199. // Since we are outside of the ng-repeat directive,
  200. // we'll have to check the state of the DOM during
  201. // each $digest phase; BUT, we only need to do this
  202. // once, so save a referene to the un-watcher.
  203. var unbindWatcher = parentScope.$watch(
  204. function() {
  205.  
  206. console.info( "Digest running." );
  207.  
  208. // Now that we're in a digest, check to see
  209. // if there are any ngRepeat items being
  210. // rendered. Since we want to know when the
  211. // list has completed, we only need the last
  212. // one we can find.
  213. var lastItem = parent.children( "*[ repeat-complete-id = '" + id + "' ]:last" );
  214.  
  215. // If no items have been rendered yet, stop.
  216. if ( ! lastItem.length ) {
  217.  
  218. return;
  219.  
  220. }
  221.  
  222. // Get the local ng-repeat scope for the item.
  223. var itemScope = lastItem.scope();
  224.  
  225. // If the item is the "last" item as defined
  226. // by the ng-repeat directive, then we know
  227. // that the ng-repeat directive has finished
  228. // rendering its list (for the first time).
  229. if ( itemScope.$last ) {
  230.  
  231. // Stop watching for changes - we only
  232. // care about the first complete rendering.
  233. unbindWatcher();
  234.  
  235. // Invoke the callback.
  236. itemScope.$eval( completeExpression );
  237.  
  238. }
  239.  
  240. }
  241. );
  242.  
  243. }
  244.  
  245. // Return the directive configuration. It's important
  246. // that this compiles before the ngRepeat directive
  247. // compiles the DOM node.
  248. return({
  249. compile: compile,
  250. priority: 1001,
  251. restrict: "A"
  252. });
  253.  
  254. }
  255. );
  256.  
  257. </script>
  258.  
  259. </body>
  260. </html>
Add Comment
Please, Sign In to add comment