@masquevil
2015-12-14T05:17:27.000000Z
字数 982
阅读 74
Angular.js
前端开发
js
Angular.js在使用的过程中,经常会有这样的需求:在ng-repeat结束后,执行某段JS。
一开始我是这么做的:
IMCtrls.directive('onRenderFinish', function($timeout){
return {
restrict:'A',
link: function($sc, element, attrs, controller){
if($sc.$last === true || $sc.$last === undefined)$sc.$eval(attrs.onRenderFinish);
}
};
});
判断 ng-repeat 到最后一个元素的时候($last 为 true),或者不在 ng-repeat 的元素上使用 onRenderFinish 的时候($last 为 undefined),执行 onRenderFinish 内的方法。
后来在使用的过程中,发现一个坑:
当使用 concat 构建 ng-repeat 元素的时候,angular 会出于性能优化的原因,不会重复渲染已经渲染过的元素。
比如下面的代码:
<!-- …… -->
<a ng-repeat="a in as" on-render-finish="fun()">{{ a.a }}</a>
<!-- …… -->
<script>
// ……
$scope.fun = function(){alert(1);};
// ……
b = [{a:1}];
$scope.as = b.concat($scope.as);
// ……
</script>
只有 b 中的元素会被重新渲染,也就是只有 b 中的元素会去查看他的 onRenderFinish。
很明显,b 中的元素 $last 恒不为 true,所以无法正确的触发 ng-repeat 结束后的 js。
经过研究,我改成了这样:
IMCtrls.directive('onRenderFinish', function($timeout){
return {
restrict:'A',
link: function($sc, element, attrs, controller){
$timeout(function(){if(!$sc.$$nextSibling)$sc.$eval(attrs.onRenderFinish);});
}
};
});
目前已经能够满足要求。