我想调用一些jQuery函数针对div表。该表由ng-repeat填充。
当我打开它的时候
$(document).ready()
我没有结果。
也
$scope.$on('$viewContentLoaded', myFunc);
没有帮助。
是否有办法在ng-repeat填充完成后立即执行函数?我读了一个关于使用自定义指令的建议,但我不知道如何使用ng-repeat和我的div…
我想调用一些jQuery函数针对div表。该表由ng-repeat填充。
当我打开它的时候
$(document).ready()
我没有结果。
也
$scope.$on('$viewContentLoaded', myFunc);
没有帮助。
是否有办法在ng-repeat填充完成后立即执行函数?我读了一个关于使用自定义指令的建议,但我不知道如何使用ng-repeat和我的div…
当前回答
与Pavel的回答相辅相成的是:
<ul>
<li ng-repeat="item in items"
ng-init="$last ? doSomething() : angular.noop()">{{item}}</li>
</ul>
不然你为什么会觉得棱角分明。不,一开始就有吗?
优点:
你不需要为此写一个指令……
其他回答
我必须在ng-repeat结束后使用MathJax渲染公式,上面的答案都没有解决我的问题,所以我做了如下。这不是一个很好的解决方案,但对我来说很有效。
<div ng-repeat="formula in controller.formulas">
<div>{{formula.string}}</div>
{{$last ? controller.render_formulas() : ""}}
</div>
这里有一个使用ng-init的简单方法,甚至不需要自定义指令。在某些情况下,它对我来说工作得很好,例如,需要在页面加载时自动滚动ng-repeat项的div到特定项,因此滚动函数需要等到ng-repeat完成对DOM的渲染后才能触发。
<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内容更新时调用一个函数,那么你必须在这个线程上使用一个自定义指令的其他答案之一。
这里是一个重复完成指令,当为真时调用指定的函数。我发现被调用的函数在做DOM操作之前必须使用interval=0的$timeout,比如在呈现的元素上初始化工具提示。jsFiddle: http://jsfiddle.net/tQw6w/
在美元范围。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>
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...
}
})
没有必要创建一个指令,特别是为了有一个ng-repeat完成事件。
Ng-init会为您带来魔力。
<div ng-repeat="thing in things" ng-init="$last && finished()">
$last确保,当最后一个元素被呈现给DOM时,finished才会被触发。
不要忘记创建$scope。完成事件。
编码快乐! !
编辑:2016年10月23日
如果你还想在数组中没有项的情况下调用完成的函数,那么你可以使用下面的解决方法
<div style="display:none" ng-init="things.length < 1 && finished()"></div>
//or
<div ng-if="things.length > 0" ng-init="finished()"></div>
只需在ng-repeat元素的顶部添加上面的行。它将检查数组是否没有任何值,并相应地调用函数。
E.g.
<div ng-if="things.length > 0" ng-init="finished()"></div>
<div ng-repeat="thing in things" ng-init="$last && finished()">
也许用ngInit和Lodash的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);
模板:
<ul>
<li ng-repeat="item in items" ng-init="refresh()">{{item}}</li>
</ul>
更新
还有一个使用三元运算符的更简单的纯AngularJS解决方案:
模板:
<ul>
<li ng-repeat="item in items" ng-init="$last ? doSomething() : null">{{item}}</li>
</ul>
注意ngInit使用预链接编译阶段——即在处理子指令之前调用表达式。这意味着仍然需要异步处理。