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

Angular JS callback after ng-repeat is completed dynamically

本文关键字:动态 JS 之后 Angular ng-repeat 回调      更新时间:2023-09-26

有大量的帖子展示了如何基于指令的回调函数,以便在ng-repeat函数完成时可以等待然后调用函数。例如,这是我的例子。

<div ng-repeat="Object in Objects" class="objectClass" on-finish-render>{{Object.Overlay}</div>

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

.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时的预期。对象变量。我的代码将等到所有对象完全渲染后再运行,字面意思是完美的。但是,如果在初始之后,我更改$scope。再次对象,我的函数仍将运行,但它不会等待完成。它实际上在控制台日志中可见,第一次绕过它会在我进入指令后但在实际发出之前暂停大约半秒钟,但在对我的 ng-repeat 进行后续更改时,它不会暂停,只是在 dom 完成渲染之前调用我的函数。

这非常烦人,任何帮助都会很棒!

关于ng-repeat,您应该了解的一件事是,它尽可能重用 DOM 元素,因此,如果您的中继器中有两个对象并添加了第三个对象,则前两个元素将不会重新渲染。只会呈现第三个,因此指令的链接函数只会为新添加的对象调用一次。

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

观察此 JSFiddle 中的行为。

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

使用 $scope.$emit 将触发$scope的事件。用$scope.$broadcast 将触发$scope事件。使用 $scope.$on是我们监听这些事件的方式。

(参考资料(

我根据您的问题提供了两种解决方案。

解决方案一

<div ng-controller="MyCtrl">
    <div ng-repeat="Object in Objects" class="objectClass" on-finish-render isolated-expression-foo="updateItem(item,temp)">{{Object|json}</div>
</div>
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);
    }
}]);

解决方案二

<div ng-controller="MyCtrl">
     <div ng-repeat="Object in Objects" class="objectClass" on-finish-render>{{Object|json}</div>
</div>
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);
    });
}]);