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

来源:互联网 发布:外国文学杂志知乎 编辑:程序博客网 时间:2024/06/07 20:05

业务中有时需要在异步获取数据并用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(移动端)轮播图巧应用【原创】

0 0