ng-repeat 完成事件

IT技术 javascript jquery angularjs angularjs-ng-repeat document-ready
2021-01-22 15:47:54

我想用表调用一些针对 div 的 jQuery 函数。该表填充了ng-repeat.

当我调用它时

$(document).ready()

我没有结果。

$scope.$on('$viewContentLoaded', myFunc);

没有帮助。

在 ng-repeat 填充完成后有什么方法可以立即执行函数吗?我已经阅读了有关使用 custom 的建议directive,但我不知道如何将它与 ng-repeat 和我的 div 一起使用...

6个回答

实际上,您应该使用指令,并且没有与 ng-Repeat 循环结束相关的事件(因为每个元素都是单独构造的,并且有自己的事件)。但是 a) using 指令可能就是你所需要的,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>

您可以像这样使用指令:

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');
  };
});

在此Plunker 中查看它的运行情况希望能帮助到你!

当然!只需将“window.alert”更改为事件触发函数,并使用 main 指令捕获它。例如,我更新了 de Plunker 来执行此操作。
2021-03-15 15:47:54
这是所有角度指令的命名约定。请参阅docs.angularjs.org/guide/directive#normalization
2021-03-20 15:47:54
Any1 知道如何让它为 ngRepeat 指令的后续渲染工作?即:链接
2021-03-28 15:47:54
建议首先包含 jQuery 库(在 Angular 之前)。这将导致所有 Angular 元素都被 jQuery(而不是 jqLit​​e)包裹。然后你可以简单地编写 element.css() 和 element.children().css() 而不是 angular.element(element).css() 和 $(element).children().css() 。另见groups.google.com/d/msg/angular/6A3Skwm59Z4/oJ0WhKGAFK0J
2021-04-04 15:47:54
我可以让myMainDirective的代码只在循环结束后执行吗?我需要更新父 div 的滚动条。
2021-04-09 15:47:54

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

<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');
    }
  };
});

观看现场演示。

如果我将控制器用作语法,这是否有效?请?不是,还有其他方法可以与控制器一起使用吗?
2021-03-22 15:47:54

没有必要创建指令,尤其是为了有一个ng-repeat完整的事件。

ng-init 为你做魔法。

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

$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>

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

例如

<div ng-if="things.length > 0" ng-init="finished()"></div>
<div ng-repeat="thing in things" ng-init="$last && finished()">
在空数组的情况下,在控制器中处理它
2021-03-15 15:47:54
修复 Vikas Bansal 答案://如果要检查数组是否没有任何值并相应地调用函数,请使用第一个 div。<div ng-if="!things.length" ng-hide="true" ng-init="finished()"></div> <div ng-repeat="事物中的事物" ng-init="$最后&&完成()">
2021-03-31 15:47:54
如果“事物”结果是一个空数组怎么办?
2021-04-04 15:47:54
@FranePoljak 我在答案中添加了解决方案。
2021-04-05 15:47:54

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

在 $scope.layoutDone 中,尝试注释掉 $timeout 行并取消注释“不正确!” 行查看工具提示中的差异。

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

    })
我不想使用 $timeout,但是当你说它可以设置为 0 时,我决定尝试一下,它运行良好。我想知道这是否是一个消化问题,是否有办法在不使用 $timeout 的情况下完成 $timeout 正在做的事情。
2021-04-01 15:47:54
你能解释一下为什么这样做吗?我正在尝试访问动态 ID,它仅在超时 0 延迟后才有效。我在几篇文章中看到了这个“hacky”解决方案,但没有人解释它为什么有效。
2021-04-02 15:47:54

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

<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);

    };
});

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

漂亮,这完成了工作。我想在文本框中自动选择文本,超时就成功了。否则,{{model.value}} 文本被选中,然后在注入数据绑定 model.value 时取消选中。
2021-04-09 15:47:54