ng-repeat动态完成后的Angular JS回调

有大量post显示如何根据指令设置回调函数,这样当ng-repeat函数完成后,您可以等待然后调用函数。 例如,这是我的例子。

{{Object.Overlay}

然后当它完成时,以下调用我的函数

 .directive('onFinishRender', function ($timeout) { return { restrict: 'A', link: function (scope, element, attr) { if (scope.$last === true) { $timeout(function () { scope.$emit('ngRepeatFinished'); }, 0); } } } }); 

完成后,这会成功调用我的函数

 $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) { //my code goes here } 

现在所有这些都完美无缺,并且第一次设置我的$ scope.Objects变量时也是如此。 我的代码将等待所有对象完全呈现然后运行,完全是完美的。 但是,如果在最初的所有内容后我再次更改$ scope.Objects,我的函数仍会运行,但它不会等待完成。 它实际上可以通过控制台日志看到,第一次循环它会在我进入指令之后但在实际发射之前暂停大约半秒,但是在我的ng-repeat的后续更改中它不会暂停并简单地调用我的函数之前dom完成渲染。

这太烦人了,任何帮助都会很棒!

Angular的$ emit,$ broadcast和$ on属于常见的“发布/订阅”设计模式,或者可以做,您可以在其中发布事件并在其他地方订阅/取消订阅。 Angular事件系统非常出色,它使事情变得完美无缺(正如您所期望的那样!)但是它背后的概念并不是那么容易掌握,你可能经常会想知道为什么事情不能像你一样工作以为他们可能。

使用$ scope。$ emit将触发$ scope范围内的事件。 使用$ scope。$ broadcast将在$ scope范围内触发一个事件。 使用$ scope。$ on是我们监听这些事件的方式。

(参考)

我根据你的问题提供了两个解决方案。

解决方案一

 
{{Object|json}
var app = angular.module('app', []); app.directive('onFinishRender', function () { return { restrict: 'A', scope: { isolatedExpressionFoo: '&' }, link: function (scope, element, attr) { if (scope.$parent.$last) { scope.isolatedExpressionFoo({ temp: "some value" }); } } }; }); app.controller('MyCtrl', ['$scope', function ($scope) { $scope.Objects = [{ id: 1, value: "test" }, { id: 2, value: "TEst2" }]; $scope.updateItem = function (item, temp) { console.log("Item param " + item.id); console.log("temp param " + temp); } }]);

解决方案二

 
{{Object|json}
var app = angular.module('app', []); app.directive('onFinishRender', function ($rootScope) { return { restrict: 'A', link: function (scope, element, attr) { if (scope.$last) { $rootScope.$broadcast("ngRepeatFinished", { temp: "some value" }); } } }; }); app.controller('MyCtrl', ['$scope', function ($scope) { $scope.Objects = [{ id: 1, value: "test" }, { id: 2, value: "TEst2" }]; $scope.$on('ngRepeatFinished', function (temp) { console.log("Item param " + temp); }); }]);

关于ng-repeat应该理解的一点是它尽可能重用DOM元素,所以如果你的转发器中有两个对象而你添加了第三个,那么前两个元素将不会被重新渲染。 只会渲染第三个,因此只会为新添加的对象调用一次指令的链接函数。

同样,如果删除项目,则不会再次运行指令的链接function。

观察这个JSFiddle中的行为。