您的位置:首页 > Web前端 > AngularJS

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

2017-04-10 18:20 676 查看
业务中有时需要在异步获取数据并用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(移动端)轮播图巧应用【原创】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: