ng-repeat完成事件

Chr*_*ruS 203 javascript jquery document-ready angularjs angularjs-ng-repeat

我想调用一些jQuery函数以div为目标.该表填充了ng-repeat.

我打电话的时候

$(document).ready()
Run Code Online (Sandbox Code Playgroud)

我没有结果.

$scope.$on('$viewContentLoaded', myFunc);
Run Code Online (Sandbox Code Playgroud)

没有帮助.

在ng-repeat群体完成后,有没有办法正确执行功能?我已经阅读了关于使用自定义的建议directive,但我不知道如何将它与ng-repeat和我的div一起使用...

Tia*_*dão 238

实际上,你应该使用指令,并且没有事件与ng-Repeat循环的结束相关联(因为每个元素是单独构造的,并且具有它自己的事件).但是a)使用指令可能就是你所需要的全部b)有一些ng-Repeat特定的属性可以用来制作你的"on ngRepeat finished"事件.

特别是,如果你想要的是款式/事件添加到整个表,你可以这样做,用的是包含所有ngRepeat元素指令.另一方面,如果要专门处理每个元素,可以在ngRepeat中使用指令,它将在创建后对每个元素起作用.

然后,还有$index,$first,$middle并且$last可以用来触发事件的性质.对于这个HTML:

<div ng-controller="Ctrl" my-main-directive>
  <div ng-repeat="thing in things" my-repeat-directive>
    thing {{thing}}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

您可以使用如下指令:

angular.module('myApp', [])
.directive('myRepeatDirective', function() {
  return function(scope, element, attrs) {
    angular.element(element).css('color','blue');
    if (scope.$last){
      window.alert("im the last!");
    }
  };
})
.directive('myMainDirective', function() {
  return function(scope, element, attrs) {
    angular.element(element).css('border','5px solid red');
  };
});
Run Code Online (Sandbox Code Playgroud)

在此Plunker中查看它的实际应用.希望能帮助到你!

  • Any1知道如何在ngRepeat指令的后续渲染中使用它吗?即:[link](http://stackoverflow.com/questions/21270845/how-do-i-create-a-callback-for-ng-repeat-orderby) (10认同)
  • 建议首先包含jQuery库(在Angular之前).这将导致所有Angular元素都用jQuery(而不是jqLit​​e)包装.然后,您可以简单地编写element.css()和element.children().css(),而不是angular.element(element).css()和$(element).children().css().另请参阅https://groups.google.com/d/msg/angular/6A3Skwm59Z4/oJ0WhKGAFK0J (9认同)
  • 当然!只需将"window.alert"更改为事件触发功能,并使用main指令捕获它.作为一个例子,我更新了de Plunker来做这件事. (2认同)

kar*_*old 67

如果您只是想在循环结束时执行一些代码,那么这是一个稍微简单的变体,不需要额外的事件处理:

<div ng-controller="Ctrl">
  <div class="thing" ng-repeat="thing in things" my-post-repeat-directive>
    thing {{thing}}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)
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');
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

观看现场演示.


Vik*_*sal 58

没有必要创建一个指令,特别是只有一个ng-repeat完整的事件.

ng-init 给你带来魔力.

  <div ng-repeat="thing in things" ng-init="$last && finished()">
Run Code Online (Sandbox Code Playgroud)

$last做肯定的,那finished只有被炒鱿鱼,当最后一个元素已经被渲染到了DOM.

不要忘记创建$scope.finished活动.

快乐编码!!

编辑:2016年10月23日

如果您还想finished在阵列中没有项目时调用该函数,则可以使用以下解决方法

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

只需在ng-repeat元素顶部添加上面的行.它将检查数组是否没有任何值并相应地调用该函数.

例如

<div ng-if="things.length > 0" ng-init="finished()"></div>
<div ng-repeat="thing in things" ng-init="$last && finished()">
Run Code Online (Sandbox Code Playgroud)


Jos*_*ter 41

这是一个repeat-done指令,在true时调用指定的函数.我发现在执行DOM操作之前,被调用的函数必须使用$ timeout和interval = 0,例如在渲染元素上初始化工具提示.jsFiddle:http://jsfiddle.net/tQw6w/

在$ scope.layoutDone中,尝试注释掉$ timeout行并取消注释"NOT CORRECT!" 行以查看工具提示中的差异.

<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>
Run Code Online (Sandbox Code Playgroud)

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...
        }

    })
Run Code Online (Sandbox Code Playgroud)


dsh*_*hap 29

这是一个简单的方法ng-init,甚至不需要自定义指令.在某些情况下,它对我来说效果很好,例如需要在页面加载时自动滚动一系列重复项目到特定项目,因此滚动功能需要等到ng-repeat完成渲染到DOM之后才能触发.

<div ng-controller="MyCtrl">
    <div ng-repeat="thing in things">
        thing: {{ thing }}
    </div>
    <div ng-init="fireEvent()"></div>
</div>
Run Code Online (Sandbox Code Playgroud)
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);

    };
});
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于最初在ng-repeat渲染后需要调用一次的函数.如果您需要在更新ng-repeat内容时调用函数,那么您必须使用自定义指令在此线程上使用其他一个答案.


deo*_*oll 27

补充Pavel的答案,更具可读性和易于理解的是:

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

为什么你认为angular.noop首先是......?

好处:

你不必为此写一个指令......

  • 为什么在使用布尔逻辑时使用三元组:`ng-init ="$ last && doSomething()"` (20认同)

Pav*_*ral 21

使用ngInitLodash的debounce方法可能有点简单,无需自定义指令:

控制器:

$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);
Run Code Online (Sandbox Code Playgroud)

模板:

<ul>
    <li ng-repeat="item in items" ng-init="refresh()">{{item}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

更新

使用三元运算符甚至有更简单的纯AngularJS解决方案:

模板:

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

请注意,ngInit使用预链接编译阶段 - 即在处理子指令之前调用表达式.这意味着仍然可能需要异步处理.