利用angular指令监听ng-repeat渲染完成后执行脚本

本文介绍如何自定义AngularJS指令来监听ng-repeat渲染完成,并展示如何使用该指令实现轮播图功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

业务中有时需要在异步获取数据并用ng-repeat遍历渲染完页面后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己动手写。有经验的同学都应该知道,在ng-repeat模板实例内部会暴露出一些特殊属性index/first/middle/last/odd/even,index会随着每次遍历(从0开始)递增,当遍历到最后一个时,last的值为true,so,通过判断last的值来监听ng-repeat的执行状态,怎么在遍历过程中拿到last的值:自定义指令

第一步:自定义指令

//自定义指令repeatFinish
 app.directive('repeatFinish', function () {
            return {
                link: function (scope, element, attr) {
                    console.log(scope.$index);
                    if (scope.$last == true) {
                        console.log('ng-repeat执行完毕');
                        scope.$eval(attr.repeatFinish)
                    }
                }
            };
        });

attr获取到的属性只是一个字符串表达式, scope. eval方法是专门执行AngularJS表达式的,通过它处理函数得以执行,这样,指令用在不同的地方,可传递不同的处理函数。

第二步:在循环的位置加入自定义的指令,并设置响应函数。

 <ul>
    <li ng-repeat="x in imgUrls track by $index" repeat-finish="renderFinish()">
     <a href="javascript:;">
        <img ng-src="{{x}}" alt="">
      </a>
   </li>
</ul>

第三步:在controller里处理设置的函数

注意:响应函数加上延时操作timeout,不然图片还没绑定好,不会显示。

            //controller里对应的处理函数
            $scope.renderFinish = function () {
                console.log('渲染完之后的操作');

                $timeout(function () {
                    console.log("我要touchslide!!!!!!");
                    TouchSlide({
                        slideCell: "#banner",//(产生轮播效果的包裹元素)
                        mainCell: "#list ul",//(产生轮播效果的元素)
                        autoPlay: true,//(自动分页)
                        titCell: "#buttons span",//(引导轮播效果的按钮元素)
                        effect: "leftLoop"//(左循环滚动)
                    });
                }, 0);
            };

完整demo:轮播图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="angular.min.js"></script>

    <script src="jquery.js"></script>
    <script src="TouchSlide.js"></script>

    <style>
        /*焦点图start*/
        #banner {
            width: 100%;
            overflow: hidden;
            position: relative;
            margin-top: 50px }

        #list {
            background-color: #2ac7f6;
        }

        #list li {
            float: left;
        }

        #list img {
            width: 100%;
        }

        #buttons {
            width: 60px;
            height: 13px;
            position: absolute;
            top: 85%;
            right: 0;
            z-index: 2;
            border-radius: 10px;
        }

        #buttons span {
            width: 8px;
            height: 8px;
            cursor: pointer;
            background: #fff;
            float: left;
            margin-left: 10.3%;
            border-radius: 50%;
            margin-top: 3%;
        }

        #buttons .on {
            background-color: #64b260;
        }

        /*焦点图end*/
    </style>
</head>

<body ng-app="suppleInfoModule" ng-controller="suppleInfoCtrl">
<div id="banner">
    <div id="list">
        <ul>
            <li ng-repeat="x in imgUrls track by $index" repeat-finish="renderFinish()">
                <a href="javascript:;">
                    <img ng-src="{{x}}" alt="" height="150px">
                </a>
            </li>
        </ul>
    </div>

    <div id="buttons">
        <span index="1" class="on"></span>
        <span index="2"></span>
        <span index="3"></span>
        <span index="4"></span>
    </div>
</div>

<script>
    (function (angular) {
        'use strict';

        var app = angular.module('suppleInfoModule', []);

        app.directive('repeatFinish', function () {
            return {
                link: function (scope, element, attr) {
                    console.log(scope.$index);
                    if (scope.$last == true) {
                        console.log('ng-repeat执行完毕');
                        scope.$eval(attr.repeatFinish)
                    }
                }
            };
        });

        app.controller('suppleInfoCtrl', function ($scope, $http, $timeout) {

            //如果图片网址只用一个,记得在ng-repeat中使用track by $index 避免报重复值的错误。
            $scope.imgUrls = [
                'http://www.runoob.com/wp-content/uploads/2014/09/c-mini-logo.png',
                'http://www.runoob.com/wp-content/uploads/2013/11/ruby-mini-logo.png',
                'http://www.runoob.com/wp-content/uploads/2015/01/cpp-mini-logo.png',
                'http://www.runoob.com/wp-content/uploads/2013/12/java.jpg',
            ];

            //controller里对应的处理函数
            $scope.renderFinish = function () {
                console.log('渲染完之后的操作');

                $timeout(function () {
                    console.log("我要touchslide!!!!!!");
                    TouchSlide({
                        slideCell: "#banner",//(产生轮播效果的包裹元素)
                        mainCell: "#list ul",//(产生轮播效果的元素)
                        autoPlay: true,//(自动分页)
                        titCell: "#buttons span",//(引导轮播效果的按钮元素)
                        effect: "leftLoop"//(左循环滚动)
                    });
                }, 0);
            };
        });
    })(window.angular);
</script>
</body>
</html>

另外一种写法,可以将函数调用直接在自定义指令时使用:

第一步:自定义指令

        app.directive('repeatFinish', function () {
            return {
                link: function (scope, element, attr) {
                    console.log(scope.$index);
                    if (scope.$last == true) {
                        console.log('ng-repeat执行完毕');
//                        scope.$eval(attr.repeatFinish)
                        scope.renderFinish();//直接调用循环完要执行的函数
                    }
                }
            };
        });

第二步:在循环的位置加入自定义的指令,不用设置响应函数。

 <ul>
            <li ng-repeat="x in imgUrls track by $index" repeat-finish>
                <a href="javascript:;">
                    <img ng-src="{{x}}" alt="" height="150px">
                </a>
            </li>
        </ul>

第三步:处理函数


            //controller里对应的处理函数
            $scope.renderFinish = function () {
                console.log('渲染完之后的操作');

                $timeout(function () {
                    console.log("我要touchslide!!!!!!");
                    TouchSlide({
                        slideCell: "#banner",//(产生轮播效果的包裹元素)
                        mainCell: "#list ul",//(产生轮播效果的元素)
                        autoPlay: true,//(自动分页)
                        titCell: "#buttons span",//(引导轮播效果的按钮元素)
                        effect: "leftLoop"//(左循环滚动)
                    });
                }, 0);
            };

完整demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="angular.min.js"></script>

    <script src="jquery.js"></script>
    <script src="TouchSlide.js"></script>

    <style>
        /*焦点图start*/
        #banner {
            width: 100%;
            overflow: hidden;
            position: relative;
            margin-top: 50px }

        #list {
            background-color: #2ac7f6;
        }

        #list li {
            float: left;
        }

        #list img {
            width: 100%;
        }

        #buttons {
            width: 60px;
            height: 13px;
            position: absolute;
            top: 85%;
            right: 0;
            z-index: 2;
            border-radius: 10px;
        }

        #buttons span {
            width: 8px;
            height: 8px;
            cursor: pointer;
            background: #fff;
            float: left;
            margin-left: 10.3%;
            border-radius: 50%;
            margin-top: 3%;
        }

        #buttons .on {
            background-color: #64b260;
        }

        /*焦点图end*/
    </style>
</head>

<body ng-app="suppleInfoModule" ng-controller="suppleInfoCtrl">
<div id="banner">
    <div id="list">
        <ul>
            <li ng-repeat="x in imgUrls track by $index" repeat-finish>
                <a href="javascript:;">
                    <img ng-src="{{x}}" alt="" height="150px">
                </a>
            </li>
        </ul>
    </div>

    <div id="buttons">
        <span index="1" class="on"></span>
        <span index="2"></span>
        <span index="3"></span>
        <span index="4"></span>
    </div>
</div>

<script>
    (function (angular) {
        'use strict';

        var app = angular.module('suppleInfoModule', []);

        app.directive('repeatFinish', function () {
            return {
                link: function (scope, element, attr) {
                    console.log(scope.$index);
                    if (scope.$last == true) {
                        console.log('ng-repeat执行完毕');
//                        scope.$eval(attr.repeatFinish)
                        scope.renderFinish();
                    }
                }
            };
        });

        app.controller('suppleInfoCtrl', function ($scope, $http, $timeout) {

            //图片网址我只用了一个,记得在ng-repeat中使用track by $index 避免报重复值的错误。
            $scope.imgUrls = [
                'http://www.runoob.com/wp-content/uploads/2014/09/c-mini-logo.png',
                'http://www.runoob.com/wp-content/uploads/2013/11/ruby-mini-logo.png',
                'http://www.runoob.com/wp-content/uploads/2015/01/cpp-mini-logo.png',
                'http://www.runoob.com/wp-content/uploads/2013/12/java.jpg',
            ];

            //controller里对应的处理函数
            $scope.renderFinish = function () {
                console.log('渲染完之后的操作');

                $timeout(function () {
                    console.log("我要touchslide!!!!!!");
                    TouchSlide({
                        slideCell: "#banner",//(产生轮播效果的包裹元素)
                        mainCell: "#list ul",//(产生轮播效果的元素)
                        autoPlay: true,//(自动分页)
                        titCell: "#buttons span",//(引导轮播效果的按钮元素)
                        effect: "leftLoop"//(左循环滚动)
                    });
                }, 0);
            };
        });
    })(window.angular);
</script>
</body>
</html>

参考:

利用angular指令监听ng-repeat渲染完成后执行脚本

AngularJS 监听某数据集渲染完成

SuperSlide(PC端)和TouchSlide(移动端)轮播图巧应用【原创】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值