1.DOMNodeRemoved事件
DOMNodeRemoved事件这里不做过多介绍,有个大概的认识,会使用即可。如下代码给content对象注册了DOMNodeRemoved事件处理函数,当content下有子元素被删除的时候,就会触发DOMNodeRemoved事件。
<script>
window.onload = function(){
var dom = document.getElementById("content");
dom.addEventListener("DOMNodeRemoved",function(event){
});
};
</script>
<body>
<div id="content">
<div></div>
<!--commet-->
<span></span>
</div>
</body>
2.ng-repeat遍历的数组为空或者长度为0的时候
当ng-repeat遍历的数组为空或者长度为0的时候,会生成一个HTML注释。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ng-repeat</title>
<script src="jquery-1.11.1.js"></script>
<script src="angular-1.2.25.js"></script>
<script>
function wholeController($scope,$rootScope,$injector)
{
$scope.dataList = null;
//$scope.dataList = [];
}
</script>
</head>
<body ng-app>
<div ng-controller="wholeController">
<div>begin</div>
<div id="content">
<div ng-repeat="item in dataList">{{item.name}}</div>
</div>
<div>end</div>
</div>
</body>
</html>
ng-repeat生成的dom元素如下,就是一段html注释。
<div id="content">
<!-- ngRepeat: item in dataList -->
</div>
3.ng-repeat中不使用track by子语句
由于angularjs数据的双向绑定特性,当scope中的数据发生改变的时候,会自动刷新界面。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ng-repeat</title>
<script src="jquery-1.11.1.js"></script>
<script src="angular-1.2.25.js"></script>
<script>
$(function(){
var domObject = $("#content").get(0);
domObject.addEventListener("DOMNodeRemoved",function(event){
console.log("some dom was deleted.");
});
});
function wholeController($scope,$rootScope,$injector)
{
$scope.dataList = [
{"id":1,"name":"a1"},
{"id":2,"name":"a2"},
{"id":3,"name":"a3"},
{"id":4,"name":"a4"}
];
$scope.first = function(){
$scope.dataList = [
{"id":1,"name":"b1"},
{"id":2,"name":"b2"},
{"id":3,"name":"b3"},
{"id":4,"name":"b4"}
];
}
}
</script>
</head>
<body ng-app>
<div ng-controller="wholeController">
<input type="button" value="first" ng-click="first();"/>
<div>begin</div>
<div id="content">
<div ng-repeat="item in dataList">{{item.name}}</div>
</div>
<div>end</div>
</div>
</body>
</html>
当点击first按钮的时候,scope中的dataList数据发生了变化,界面会自动刷新。如果要实现dom的刷新有2种方式:
方式一:删除之前所有存在的dom,然后重新生成dom。
方式二:重用之前的dom元素,仅仅更新dom元素的属性。
在没有使用track by的情况下,angular采用的是方式一,这一点可以通过我们注册的DOMNodeRemoved事件处理函数得到证实。我们知道dom的频繁操作是非常耗费性能的,那为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,ng-repeat不知道怎么替换。在没有使用track by的情况下,我们可以看到 ng-repeat 往数组里每个元素加了一个 $$hashKey 的属性:
这个 key 是由 Angular 内部的 nextUid() 方法生成,类似数据库自增,但是是使用字符串。现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key, 所以根本没办法重用已有的 Dom 元素。那怎么解决这个问题呢?就是使用track by子语句。将ng-repeat改成下面的方式1或者方式2,就可以发现没有dom删除事件。
<!--方式1-->
<div ng-repeat="item in dataList track by item.id">{{item.name}}</div>
<!--方式2-->
<div ng-repeat="item in dataList track by $index">{{item.name}}</div>
4.数组长度未变,但是顺序发生了变化
上面的代码中,点击first按钮,dataList只是name属性值发生了改变,数组长度和顺序都没有发生变化。
[
{"id":1,"name":"a1"},
{"id":2,"name":"a2"},
{"id":3,"name":"a3"},
{"id":4,"name":"a4"}
];
变成
[
{"id":1,"name":"b1"},
{"id":2,"name":"b2"},
{"id":3,"name":"b3"},
{"id":4,"name":"b4"}
];
如果我们改变dataList中元素的顺序呢?
[
{"id":1,"name":"a1"},
{"id":2,"name":"a2"},
{"id":3,"name":"a3"},
{"id":4,"name":"a4"}
];
变成
[
{"id":4,"name":"b1"},
{"id":2,"name":"b2"},
{"id":3,"name":"b3"},
{"id":1,"name":"b4"}
];
下面这段代码中,我们改变dataList的顺序,然后使用track by $index和track by item.id看看是什么效果。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ng-repeat</title>
<script src="jquery-1.11.1.js"></script>
<script src="angular-1.2.25.js"></script>
<script>
$(function(){
var domObject = $("#content").get(0);
domObject.addEventListener("DOMNodeRemoved",function(event){
console.log("some dom was deleted."+event.target);
});
});
function wholeController($scope,$rootScope,$injector)
{
$scope.dataList = [
{"id":1,"name":"a1"},
{"id":2,"name":"a2"},
{"id":3,"name":"a3"},
{"id":4,"name":"a4"}
];
$scope.first = function(){
$scope.dataList = [
{"id":4,"name":"b1"},
{"id":2,"name":"b2"},
{"id":3,"name":"b3"},
{"id":1,"name":"b4"}
];
}
}
</script>
</head>
<body ng-app>
<div ng-controller="wholeController">
<input type="button" value="first" ng-click="first();"/>
<div>begin</div>
<div id="content">
<div ng-repeat="item in dataList track by item.id">{{item.name}}</div>
<!--
<div ng-repeat="item in dataList track by $index">{{item.name}}</div>
-->
</div>
<div>end</div>
</div>
</body>
</html>
可以看到使用track by $index的时候,不会发生dom删除事件,即是更新dom元素, 而不是先删除再新建。当使用track by item.id的时候,会发生dom删除事件。也就是说,当数组中元素顺序改变的时候,使用track by item.id与不使用track by没有什么差别。大家可以试试看当数组的长度发生变化时,ng-repeat的表现是什么样子的。
http://www.cnblogs.com/MigCoder/p/3930264.html