ng-repeat动态完成后的Angular JS回调 [英] Angular JS callback after ng-repeat is completed dynamically

查看:26
本文介绍了ng-repeat动态完成后的Angular JS回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

.directive('onFinishRender', function ($timeout) {返回 {限制:'A',链接:函数(范围、元素、属性){if (scope.$last === true) {$超时(函数(){scope.$emit('ngRepeatFinished');}, 0);}}}});

当它完成时,这成功地调用了我的函数

$scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent){//我的代码在这里}

现在,当我第一次设置 $scope.Objects 变量时,所有这些都完美地工作并符合预期.我的代码将等到所有对象都完全呈现然后运行,简直完美.但是,如果在初始一切之后我再次更改 $scope.Objects,我的函数仍将运行,但不会等待完成.它实际上在控制台日志中可见,第一轮它会在我进入指令后但在实际发出之前暂停大约半秒,但是在对我的 ng-repeat 进行后续更改时,它不会暂停并且只是在之前调用我的函数dom 已完成渲染.

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

解决方案

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

使用 $scope.$emit 将在 $scope 上触发一个事件.使用$scope.$broadcast 将在 $scope 下触发一个事件.使用 $scope.$on是我们监听这些事件的方式.

(参考)

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

方案一

<div ng-repeat=对象中的对象"类=对象类"on-finish-render isolated-expression-foo=updateItem(item,temp)">{{Object|json}</div>

var app = angular.module('app', []);app.directive('onFinishRender', function () {返回 {限制:'A',范围: {isolatedExpressionFoo: '&'},链接:函数(范围、元素、属性){如果(范围.$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.id);console.log("临时参数" + 温度);}}]);

方案二

<div ng-repeat=对象中的对象"类=对象类"on-finish-render>{{Object|json}</div>

var app = angular.module('app', []);app.directive('onFinishRender', function ($rootScope) {返回 {限制:'A',链接:函数(范围、元素、属性){如果(范围.$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) {控制台日志(项目参数"+温度);});}]);

There are tons of posts showing how to have callback functions based on a directive so that when an ng-repeat function is finished you can wait and then call a function. For example here is my example.

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

Then when it is completed the following calls my function

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

This successfully calls my function below when it is completed

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

Now all of that works perfectly and as intended the first time I set my $scope.Objects variable. My code will wait until all objects are fully rendered and then runs, literally perfect. However if after the initial everything I change $scope.Objects again, my function will still run but it will NOT wait for the completion. Its actually visible with console logs, the first go round it will pause for about half a second after I go into the directive but before the actual emit, but on subsequent changes to my ng-repeat it does not pause and simply calls my function before the dom is finished rendering.

This is super annoying and any help would be great!

解决方案

Angular’s $emit, $broadcast and $on fall under the common "publish/subscribe" design pattern, or can do, in which you’d publish an event and subscribe/unsubscribe to it somewhere else. The Angular event system is brilliant, it makes things flawless and easy to do (as you’d expect!) but the concept behind it isn’t so simple to master and you can often be left wondering why things don’t work as you thought they might.

Using $scope.$emit will fire an event up the $scope. Using $scope.$broadcast will fire an event down the $scope. Using $scope.$on is how we listen for these events.

(reference)

I have provided two solution according to your problem.

Solution One

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

Solution Two

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

}]);

这篇关于ng-repeat动态完成后的Angular JS回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆