ng-repeat finish event

前端 未结 15 2620
盖世英雄少女心
盖世英雄少女心 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:35

    Here is a repeat-done directive that calls a specified function when true. I have found that the called function must use $timeout with interval=0 before doing DOM manipulation, such as initializing tooltips on the rendered elements. jsFiddle: http://jsfiddle.net/tQw6w/

    In $scope.layoutDone, try commenting out the $timeout line and uncommenting the "NOT CORRECT!" line to see the difference in the tooltips.

    <ul>
        <li ng-repeat="feed in feedList" repeat-done="layoutDone()" ng-cloak>
        <a href="{{feed}}" title="view at {{feed | hostName}}" data-toggle="tooltip">{{feed | strip_http}}</a>
        </li>
    </ul>
    

    JS:

    angular.module('Repeat_Demo', [])
    
        .directive('repeatDone', function() {
            return function(scope, element, attrs) {
                if (scope.$last) { // all are rendered
                    scope.$eval(attrs.repeatDone);
                }
            }
        })
    
        .filter('strip_http', function() {
            return function(str) {
                var http = "http://";
                return (str.indexOf(http) == 0) ? str.substr(http.length) : str;
            }
        })
    
        .filter('hostName', function() {
            return function(str) {
                var urlParser = document.createElement('a');
                urlParser.href = str;
                return urlParser.hostname;
            }
        })
    
        .controller('AppCtrl', function($scope, $timeout) {
    
            $scope.feedList = [
                'http://feeds.feedburner.com/TEDTalks_video',
                'http://feeds.nationalgeographic.com/ng/photography/photo-of-the-day/',
                'http://sfbay.craigslist.org/eng/index.rss',
                'http://www.slate.com/blogs/trending.fulltext.all.10.rss',
                'http://feeds.current.com/homepage/en_US.rss',
                'http://feeds.current.com/items/popular.rss',
                'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'
            ];
    
            $scope.layoutDone = function() {
                //$('a[data-toggle="tooltip"]').tooltip(); // NOT CORRECT!
                $timeout(function() { $('a[data-toggle="tooltip"]').tooltip(); }, 0); // wait...
            }
    
        })
    
    0 讨论(0)
  • 2020-11-22 02:35

    If you simply wants to change the class name so it will rendered differently, below code would do the trick.

    <div>
    <div ng-show="loginsuccess" ng-repeat="i in itemList">
        <div id="{{i.status}}" class="{{i.status}}">
            <div class="listitems">{{i.item}}</div>
            <div class="listitems">{{i.qty}}</div>
            <div class="listitems">{{i.date}}</div>
            <div class="listbutton">
                <button ng-click="UpdateStatus(i.$id)" class="btn"><span>Done</span></button>
                <button ng-click="changeClass()" class="btn"><span>Remove</span></button>
            </div>
        <hr>
    </div>
    

    This code worked for me when I had a similar requirement to render the shopped item in my shopping list in Strick trough font.

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

    This is an improvement of the ideas expressed in other answers in order to show how to gain access to the ngRepeat properties ($index, $first, $middle, $last, $even, $odd) when using declarative syntax and isolate scope (Google recommended best practice) with an element-directive. Note the primary difference: scope.$parent.$last.

    angular.module('myApp', [])
    .directive('myRepeatDirective', function() {
      return {
        restrict: 'E',
        scope: {
          someAttr: '='
        },
        link: function(scope, element, attrs) {
          angular.element(element).css('color','blue');
          if (scope.$parent.$last){
            window.alert("im the last!");
          }
        }
      };
    });
    
    0 讨论(0)
  • 2020-11-22 02:36

    I had to render formulas using MathJax after ng-repeat ends, none of the above answers solved my problem, so I made like below. It's not a nice solution, but worked for me...

    <div ng-repeat="formula in controller.formulas">
        <div>{{formula.string}}</div>
        {{$last ? controller.render_formulas() : ""}}
    </div>
    
    0 讨论(0)
  • 2020-11-22 02:37

    Complementing Pavel's answer, something more readable and easily understandable would be:

    <ul>
        <li ng-repeat="item in items" 
            ng-init="$last ? doSomething() : angular.noop()">{{item}}</li>
    </ul>
    

    Why else do you think angular.noop is there in the first place...?

    Advantages:

    You don't have to write a directive for this...

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

    Maybe a bit simpler approach with ngInit and Lodash's debounce method without the need of custom directive:

    Controller:

    $scope.items = [1, 2, 3, 4];
    
    $scope.refresh = _.debounce(function() {
        // Debounce has timeout and prevents multiple calls, so this will be called 
        // once the iteration finishes
        console.log('we are done');
    }, 0);
    

    Template:

    <ul>
        <li ng-repeat="item in items" ng-init="refresh()">{{item}}</li>
    </ul>
    

    Update

    There is even simpler pure AngularJS solution using ternary operator:

    Template:

    <ul>
        <li ng-repeat="item in items" ng-init="$last ? doSomething() : null">{{item}}</li>
    </ul>
    

    Be aware that ngInit uses pre-link compilation phase - i.e. the expression is invoked before child directives are processed. This means that still an asynchronous processing might be required.

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