angular 列表渲染机制
watchCollection:监听集合元素的变化,而不能监听到集合元素内部的属性变化,只要集合中元素的引用没有发生变化,则认为无变化。用这个api也可以监听普通对象的第一层属性变化。
watch:监听数据有没有发生变化,引用有无发生变化、原始类型数值有无发生变化等。除非指定第三个参数为true,否则不会对比对象的内层(多层)属性的变化,而仅仅对比引用。
ngRepeat的检测 = watchCollection + watch(第三个参数为true)。
默认情况下,ngRepeat使用列表元素对象的$$haskKey来标识关联对应的dom(angular会为不同引用的对象创建不同的$$hashKey),如果列表元素不是对象而是原始数据类型,则以元素的值来标识。在同一个列表中,标识必须唯一,否则报错,也可以通过track by xx 来自己指定标识的方式,如track by $index 就是用列表的索引来进行标识。
ngRepeat会为每个单元创建一个作用域,然后把当前循环的状态($index,$first等)传递到这个作用域中,因为这个作用域是原型继承于外部作用域的,所以当ngRepeat出现嵌套的时候,可以通过ngInit把外层循环的index记录下来共内层循环使用:
<div ng-repeat="item in ones" ng-init="outerIndex=$index">
<span ng-repeat="item in twos" >the outer index is {{outerIndex }}</span> <br>
</div>
列表优化
默认情况下,当列表中的元素引用发生变化(脏检测时发现的,使用的是watchCollection),angular仅仅会把对应变化的元素item的dom进行移除,然后重新生成一个新的dom替换进去,其余不需要变化。这就意味着当整个列表都发生变化时,整个dom列表会全部移除,生成新的全部替换进去。
有没有办法改变了列表item的引用,却不生成新的dom进行替换呢?答案是可以的,但要指定track by。以下进行测试:
<body ng-app="app">
<div ng-repeat="item in ones">{{item}}</div>
<button ng-click="changeArr()">changeArr</button>
<button ng-click="getVal()">getVal</button>
</body>
<script>
var app = angular.module("app",[]);
app.run(function($rootScope){
$rootScope.ones = [{a:1},{a:2},{a:3}]; setTimeout(setVal,100); $rootScope.changeArr = function(){
$rootScope.ones[0] = {a:1,b:2};
}
$rootScope.getVal = function(){
console.log(document.querySelectorAll("div")[0].data)
console.log(document.querySelectorAll("div")[1].data)
}
});
function setVal(){
document.querySelectorAll("div")[0].data = 0;
document.querySelectorAll("div")[1].data = 1;
}
</script>
以上代码中,点击getVal,输出01,接着点击changeArr,更换了一个列表元素,界面上出现变化,接着点击getVal,输出undefined 1 。
结论:没有使用track by,当列表元素的引用被替换时,对应的dom也会被替换,之前绑定在上面的数据自然也就没了。
接下来使用track by 进行dom复用:
<div ng-repeat="item in ones track by item.a">{{item}}</div>
修改后,点击changeArr,界面发生变化,接着点击getVal,输出01 。
根据以上现象总结angular的列表渲染机制:

所以优化的策略就是,显式指定track by,能减少dom的创建,有利于dom的复用。
angular 列表渲染机制的更多相关文章
- angular,vue,react的基本语法—双向数据绑定、条件渲染、列表渲染、angular小案例
基本语法: 1.双向数据绑定 vue 指令:v-model="msg" react constructor(){ this.state{ msg:"双向数据绑定" ...
- 03-Vue入门系列之Vue列表渲染及条件渲染实战
3.1. 条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue帮我们提供了一个v- ...
- 前端MVC Vue2学习总结(四)——条件渲染、列表渲染、事件处理器
一.条件渲染 1.1.v-if 在字符串模板中,如 Handlebars ,我们得像这样写一个条件块: <!-- Handlebars 模板 --> {{#if ok}} <h1&g ...
- Vue入门系列(三)之Vue列表渲染及条件渲染实战
Vue官网: https://cn.vuejs.org/v2/guide/forms.html#基础用法 [入门系列] (一) http://www.cnblogs.com/gdsblog/p/78 ...
- vue基础——列表渲染
列表渲染 用 v-for 把一个数组对应为一组元素 我们用 v-for 指令根据一组数组的选项列表进行渲染.v-for 指令需要使用 item in items 形式的特殊语法, items 是源数据 ...
- Vue 列表渲染及条件渲染实战
条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue 帮我们提供了一个v-if的指 ...
- vue 条件渲染与列表渲染
本文是对官方文档的整理 因为 v-if 是一个指令,所以必须将它添加到一个元素上.但是如果想切换多个元素呢?此时可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v ...
- 【03】Vue 之列表渲染及条件渲染
3.1. 条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue帮我们提供了一个v- ...
- vue基础---列表渲染
首先简单回顾下v-for‘指令 <ol id="list_area"> <li v-for="book in books">{{book ...
随机推荐
- java string(转)
初探Java字符串 优化变成了忧患:String.split引发的“内存泄露” String是java中的无处不在的类,使用也很简单.初学java,就已经有字符串是不可变的盖棺定论,解释通常是:它是f ...
- Windows类标识符及其妙用
Windows类标识符 百度百科这样解释: Windows的类标识符class identifier也称为CLASSID或CLSID,是与某一个类对象相联系的唯一标记(UUID).一个准备创建多个对象 ...
- PostgreSQL-8-数据合并
-- 1.JOIN与UNION的区别详解 CREATE TABLE t1(id int,value1 text); ,,,'c'); -- 创建表格t1 CREATE TABLE t2(id int, ...
- Codeforces Round #497 (Div. 2)B. Turn the Rectangles
Bryce1010模板 http://codeforces.com/contest/1008/problems #include <bits/stdc++.h> using namespa ...
- PHP 字符 正则表达式 +,*,?
1.“/”是定界符,“/”定界符之间的部分就是将要在目标对象中进行匹配的模式.同时为了正则更加灵活,引入了元字符,即“+”, “*”,以及 “?”. (1)“+”元字符规定其前导字符必须在目标对象中连 ...
- 安卓新的联网方式 Volley的使用(2)
如果使用volley 获取 网络图片 最好还是用 Volley 提供的NetworkImageView类, 可以很轻松的 完成工作, 而且他可以设置缓存, lru 和 sd卡的缓存.一些都封装好了. ...
- box-shadow四周阴影
box-shadow 前面两个值为 纵向阴影 和 横向阴影 把这两个值都设置为 0 就是四边都有阴影 border:#074A99 0px solid; box-shadow: 0 0 10px #0 ...
- Webservice相关的知识
一.利用jdk web服务api实现,这里使用基于 SOAP message 的 Web 服务 1.首先建立一个Web services EndPoint: package Hello; import ...
- (转载)最近总是遇到各种 IEbug,mark一下,学习到了,转载出处:http://www.cnblogs.com/ruomeng/p/5332814.html
本文分享下我在项目中积累的IE8+兼容性问题的解决方法.根据我的实践经验,如果你在写HTML/CSS时候是按照W3C推荐的方式写的,然后下面的几点都关注过,那么基本上很大一部分IE8+兼容性问题都OK ...
- bufferedinputStream操作
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java ...