ng-repeat finish event

前端 未结 15 2627
盖世英雄少女心
盖世英雄少女心 2020-11-22 02:15

I want to call some jQuery function targeting div with table. That table is populated with ng-repeat.

When I call it on

$(document).r         


        
相关标签:
15条回答
  • 2020-11-22 02:47

    i would like to add another answer, since the preceding answers takes it that the code needed to run after the ngRepeat is done is an angular code, which in that case all answers above give a great and simple solution, some more generic than others, and in case its important the digest life cycle stage you can take a look at Ben Nadel's blog about it, with the exception of using $parse instead of $eval.

    but in my experience, as the OP states, its usually running some JQuery plugins or methods on the finnaly compiled DOM, which in that case i found that the most simple solution is to create a directive with a setTimeout, since the setTimeout function gets pushed to the end of the queue of the browser, its always right after everything is done in angular, usually ngReapet which continues after its parents postLinking function

    angular.module('myApp', [])
    .directive('pluginNameOrWhatever', function() {
      return function(scope, element, attrs) {        
        setTimeout(function doWork(){
          //jquery code and plugins
        }, 0);        
      };
    });
    

    for whoever wondering that in that case why not to use $timeout, its that it causes another digest cycle that is completely unnecessary

    0 讨论(0)
  • 2020-11-22 02:49
    <div ng-repeat="i in items">
            <label>{{i.Name}}</label>            
            <div ng-if="$last" ng-init="ngRepeatFinished()"></div>            
    </div>
    

    My solution was to add a div to call a function if the item was the last in a repeat.

    0 讨论(0)
  • 2020-11-22 02:54

    If you simply want to execute some code at the end of the loop, here's a slightly simpler variation that doesn't require extra event handling:

    <div ng-controller="Ctrl">
      <div class="thing" ng-repeat="thing in things" my-post-repeat-directive>
        thing {{thing}}
      </div>
    </div>
    
    function Ctrl($scope) {
      $scope.things = [
        'A', 'B', 'C'  
      ];
    }
    
    angular.module('myApp', [])
    .directive('myPostRepeatDirective', function() {
      return function(scope, element, attrs) {
        if (scope.$last){
          // iteration is complete, do whatever post-processing
          // is necessary
          element.parent().css('border', '1px solid black');
        }
      };
    });
    

    See a live demo.

    0 讨论(0)
  • 2020-11-22 02:55

    There is no need of creating a directive especially just to have a ng-repeat complete event.

    ng-init does the magic for you.

      <div ng-repeat="thing in things" ng-init="$last && finished()">
    

    the $last makes sure, that finished only gets fired, when the last element has been rendered to the DOM.

    Do not forget to create $scope.finished event.

    Happy Coding!!

    EDIT: 23 Oct 2016

    In case you also want to call the finished function when there is no item in the array then you may use the following workaround

    <div style="display:none" ng-init="things.length < 1 && finished()"></div>
    //or
    <div ng-if="things.length > 0" ng-init="finished()"></div>
    

    Just add the above line on the top of the ng-repeat element. It will check if the array is not having any value and call the function accordingly.

    E.g.

    <div ng-if="things.length > 0" ng-init="finished()"></div>
    <div ng-repeat="thing in things" ng-init="$last && finished()">
    
    0 讨论(0)
  • 2020-11-22 02:56

    It may also be necessary when you check the scope.$last variable to wrap your trigger with a setTimeout(someFn, 0). A setTimeout 0 is an accepted technique in javascript and it was imperative for my directive to run correctly.

    0 讨论(0)
  • 2020-11-22 02:59

    Here's a simple approach using ng-init that doesn't even require a custom directive. It's worked well for me in certain scenarios e.g. needing to auto-scroll a div of ng-repeated items to a particular item on page load, so the scrolling function needs to wait until the ng-repeat has finished rendering to the DOM before it can fire.

    <div ng-controller="MyCtrl">
        <div ng-repeat="thing in things">
            thing: {{ thing }}
        </div>
        <div ng-init="fireEvent()"></div>
    </div>
    

    myModule.controller('MyCtrl', function($scope, $timeout){
        $scope.things = ['A', 'B', 'C'];
    
        $scope.fireEvent = function(){
    
            // This will only run after the ng-repeat has rendered its things to the DOM
            $timeout(function(){
                $scope.$broadcast('thingsRendered');
            }, 0);
    
        };
    });
    

    Note that this is only useful for functions you need to call one time after the ng-repeat renders initially. If you need to call a function whenever the ng-repeat contents are updated then you'll have to use one of the other answers on this thread with a custom directive.

    0 讨论(0)
提交回复
热议问题