Oliwans'blog

不会写影评的摄影师不是好的FED

巧用ng-repeat来展示个性化内容的三种方法


  ng-repeat是angular.js自带的指令,作用是循环数组克隆展示html,不过它循环克隆出来的都是带有同样的DOM,如果想做个性化的功能,就不那么容易实现了,这里主要介绍两种方法,当然都是自己总结出来的,有不妥的地方欢迎指正:


1.ng-repeat 双层循环


1
2
3
4
5
6
7
8
9
 <a href="#/tab/KHReport/{{myHM.COURSE_ID}}/{{myHM.authorTag}}" class="zkht-menu-sense-item" ng-show="showKH" ng-repeat = "myHM in myHMs" ng-click="addHot(myHM.COURSE_ID)">
<h6>{{myHM.COURSE_NAME}}</h6>
<p class="zkht-question-profile">{{myHM.TITLE}}</p>
<p class="zkht-sense-item-bottom">
<img ng-repeat="img in myHM.userList" ng-src="{{img.pcImg}}" err-src="img/defaultFace.png">
<span class="zkht-right">热度{{myHM.COURSE_HEAT}}</span>
<img class="zkht-right zkht-fire-img" src="img/fire.png">
</p>
</a>

这段项目里的代码是使用了双层嵌套循环,外层是myHM in myHMs来实现,内层是img in myHM.userList的循环来保证实现不同的头像,这样达成的效果是每项大的内容中分别显示不同数量的img图片头像,从而达到区分项的目的,而所引用的后台数据是由一个大数组内嵌套一个包含多个小数组的userList对象,从而实现的。


2.使用eval


eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。其实说白了eval()就是一个执行语句,只不过只能操作字符串,相当于一个简略版的function,不过与ng-repeat搭配使用功能则强大了不少,还是刚才那段代码,中间加了些东西

1
2
3
4
5
6
7
8
9
10
<a href="#/tab/KHReport/{{myHM.COURSE_ID}}/{{myHM.authorTag}}" class="zkht-menu-sense-item" ng-show="showKH" ng-repeat = "myHM in myHMs | filter:searchCourseQuestions" ng-click="addHot(myHM.COURSE_ID)">
<span class="zkht-my-question" ng-show="myGiveQuestions{{$index}}">我出题</span>
<h6>{{myHM.COURSE_NAME}}</h6>
<p class="zkht-question-profile">{{myHM.TITLE}}</p>
<p class="zkht-sense-item-bottom">
<img ng-repeat="img in myHM.userList" ng-src="{{img.pcImg}}" err-src="img/defaultFace.png">
<span class="zkht-right">热度{{myHM.COURSE_HEAT}}</span>
<img class="zkht-right zkht-fire-img" src="img/fire.png">
</p>
</a>

controller中的代码为

1
2
3
4
5
6
7
8
9
10
11
12
13
for(i in data.data.records){
eval('$scope.myGiveQuestions'+i+ '=false');
for(j in data.data.records[i].userList){
if (data.data.records[i].userList[j].pcImg.indexOf('http')!=0) {
data.data.records[i].userList[j].pcImg=rootUrl + data.data.records[i].userList[j].pcImg;
}else{
data.data.records[i].userList[j].pcImg=data.data.records[i].userList[j].pcImg;
}
}
if (data.data.records[i].authorTag) {
eval('$scope.myGiveQuestions'+i+ '=true');
}
}

上面两段代码的作用是为了让后台传输的数据中包含authorTag的项显示“我出题”标识,正常不能随便改变ng-repeat中的DOM元素,而这种可有可无的参数也不能用双层嵌套来显示,所以就采用了eval()的方法来识别,通过改变字符串的内容,配合ng-if或ng-show,可以达到个别显示的效果。


3.个性化内容并非数组形式传入,使用$index + eval()


还有一种特殊的情况,即所要展示的个性化内容后台数据并非以数组形式传入,这时不能采用嵌套ng-repeat的方法,而单独采用eval()也不能保证每项内部数组的个数的不同,这时就需要$index出场了

1
2
3
4
5
6
7
8
9
10
11
<a href="#/tab/myQuestionItemShow/{{question.id}}" data-name="{{$index}}" class="zkth-myQuestionBank-itemsigle" ng-repeat="question in questions | filter:filterQuestion">
<h2>{{question.questions_name}}</h2>
<p ng-show="Show{{$index}}1">A&nbsp;&nbsp;{{question.optiona}}</p>
<p ng-show="Show{{$index}}2">B&nbsp;&nbsp;{{question.optionb}}</p>
<p ng-show="Show{{$index}}3">C&nbsp;&nbsp;{{question.optionc}}</p>
<p ng-show="Show{{$index}}4">D&nbsp;&nbsp;{{question.optiond}}</p>
<div class="tip">
<!-- <span>标签</span> -->
<span class="time">{{question.createdate}}</span>
</div>
</a>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (var i = 0; i < data.data.records.length; i++) {
eval('$scope.Show'+i+ '1' +'=true');
eval('$scope.Show'+i+ '2' +'=true');
eval('$scope.Show'+i+ '3' +'=true');
eval('$scope.Show'+i+ '4' +'=true');
if (!data.data.records[i].optiona) {
eval('$scope.Show'+i+ '1' +'=false');
}
if (!data.data.records[i].optionb) {
eval('$scope.Show'+i+ '2' +'=false');
}
if (!data.data.records[i].optionc) {
eval('$scope.Show'+i+ '3' +'=false');
}
if (!data.data.records[i].optiond) {
eval('$scope.Show'+i+ '4' +'=false');
}
};

上面两段代码指一套题目,每道题的选项个数是不同的,有选项就让她显示,无选项就不显示,$index指代的是每个选项的索引,然后根据每个大的题目的索引来遍历数组,用eval()来单独控制各小选项的显示和隐藏,这种方法主要针对于个性化内容多,但不以数组的形式传过来的方式

以上便是我在开发中总结的三种方式

Oliwans

个人博客技术、观点、见解分享者;我会在这里分享工作中的问题;兴趣方面的观点;生活中的感悟。

Proudly published with Hexo