在项目中,遇到一个问题,Angular中的ng-repeat中,track by和order by同时使用时候,order by失效了。
我们先来看一下ng-repeat的工作原理。
这里有一个Demo:
1.原始状态
index.html
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<body ng-app="app" ng-controller="ctrl">
<div ng-repeat="person in peoples " >
<span>**************************************span>
<ui>
<li>{!person.name!}li>
<li>{!person.age!}li>
<li>{!person.country!}li>
ui>
<div ng-if="person.age=='12'">
<span>12>>>>>>>span>
div>
<div ng-if="person.age=='21'">
<span>21>>>>>>>span>
div>
<div ng-if="person.age=='19'">
<span>19>>>>>>>span>
div>
<script src="angular.js">script>
<script src="controller.js">script>
body>
html>
controller.js
/**
*
*/
var app = angular.module('app',[]);
app.controller('ctrl',function($scope){
$scope.peoples=[{
age: 12,
name:'Jesus',
country:'spain'
},
{
age: 21,
name:'Dave',
country:'USA'
},
{
age: 19,
name:'Carolina',
country:'Italy'
}];
$scope.order = 'name';
});
效果如下:
我们可以看到,ng-repeat精确的显示了我们的所有数据。
2.然后对,index.html中做一下更改,
<div ng-repeat="person in peoples | orderBy: order" >
效果如下:
我们看到,这里ng-repeat按照我们的设置,按姓名排了序。
3.我们再来做一下更改
<div ng-repeat="person in peoples track by person.age | orderBy: order " >
4.在angular1.2以后,加入了一个新的属性,track by。当没有这个属性的时候
<div ng-repeat="person in peoples " >
ng-repeat默认的为每一个循环的对象添加一个$$hashkey, 这个属性是自增的,有点类似于数据库中的id自增,不过是个字符串类型。
当我们的数据发生变化时(没有track by的情况下),ng-repeat会重新的刷新我们的Dom树,这里的刷新是指的删除掉所有已有的元素,然后重新生成Dom节点,并编号。这会导致我们的页面可能会有频繁的刷新,可能会造成卡顿或者性能降低。
当我们加入track by这个属性的时候
<div ng-repeat="person in peoples track by person.age" >
这个时候,ng-repeat会按照我们指定的编码去标示一个对象,并在数据发生变化时,去更新这个Dom,而不是重新生成,这里也要求我们指定的对象是唯一的。比如这里的person.age就不可以相同。否则会报错。
如果我们再引入orderBy就看到orderBy和track by同时出现的时候,orderBy失效了。其实,是我们写的语法不正确。
正确的语法是这样的:
<div ng-repeat="person in peoples | orderBy: order track by person.age" >
一定要注意track by是在orderBy后面的。
效果如下:
按照惯例,我们列出一些可能需要的参考资料:
1.http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/
2.http://www.tuicool.com/articles/YvYJBrV
3.http://www.colabug.com/thread-1152220-1-1.html