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 列表渲染机制的更多相关文章

  1. angular,vue,react的基本语法—双向数据绑定、条件渲染、列表渲染、angular小案例

    基本语法: 1.双向数据绑定 vue 指令:v-model="msg" react constructor(){ this.state{ msg:"双向数据绑定" ...

  2. 03-Vue入门系列之Vue列表渲染及条件渲染实战

    3.1. 条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue帮我们提供了一个v- ...

  3. 前端MVC Vue2学习总结(四)——条件渲染、列表渲染、事件处理器

    一.条件渲染 1.1.v-if 在字符串模板中,如 Handlebars ,我们得像这样写一个条件块: <!-- Handlebars 模板 --> {{#if ok}} <h1&g ...

  4. Vue入门系列(三)之Vue列表渲染及条件渲染实战

    Vue官网: https://cn.vuejs.org/v2/guide/forms.html#基础用法 [入门系列] (一)  http://www.cnblogs.com/gdsblog/p/78 ...

  5. vue基础——列表渲染

    列表渲染 用 v-for 把一个数组对应为一组元素 我们用 v-for 指令根据一组数组的选项列表进行渲染.v-for 指令需要使用 item in items 形式的特殊语法, items 是源数据 ...

  6. Vue 列表渲染及条件渲染实战

    条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue 帮我们提供了一个v-if的指 ...

  7. vue 条件渲染与列表渲染

    本文是对官方文档的整理 因为 v-if 是一个指令,所以必须将它添加到一个元素上.但是如果想切换多个元素呢?此时可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v ...

  8. 【03】Vue 之列表渲染及条件渲染

    3.1. 条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue帮我们提供了一个v- ...

  9. vue基础---列表渲染

    首先简单回顾下v-for‘指令 <ol id="list_area"> <li v-for="book in books">{{book ...

随机推荐

  1. [題解](最短路)luogu_P2384最短路

    hack: 4 4 1 2 10000 2 3 10000 3 4 10000 1 4 10000 答案:13 不能邊最短路邊取模,因為取模后最大值不一定為原來最大值,所以利用log(m*n)=log ...

  2. saltstack_API接口

    1 介绍 saltstack部署完后,要和master交互,就需要使用/usr/bin/salt这个工具.but..我不想手动到salt服务器上去执行这个命令,而是让web工具来调用salt. sal ...

  3. Curious Array Codeforces - 407C(高阶差分(?)) || sequence

    https://codeforces.com/problemset/problem/407/C (自用,勿看) 手模一下找一找规律,可以发现,对于一个修改(l,r,k),相当于在[l,r]内各位分别加 ...

  4. 阿里云ECS基础知识01

  5. struts2的@Result annotation 如何添加params,并且在页面取值

    http://www.bubuko.com/infodetail-2492575.html .............................................. 标签:lai  ...

  6. spring boot使用AbstractXlsView导出excel

    一.maven依赖jar包 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi ...

  7. android开发学习 ------- debug 和 release版本执行结果不同

    在debug上测试成功的,release上测试不成功,就想着怎么将 release 版本进行调试一下.还好 Android Studio 3.0是可以进行调试apk的 可以显示log,自己看自己的逻辑 ...

  8. Sql Server的两个小技巧

    创建表结构 CREATE TABLE test( ,) NOT NULL PRIMARY KEY, ) COLLATE Chinese_PRC_CI_AS NULL, createdTime DATE ...

  9. Java语言中自动生成随机数

    参考原文:http://zhidao.baidu.com/link?url=nB3BT69wmUAiSPfKGgK5Q7HOFFP9AIE04AthreRd9yYcwKhUQsQRWlMdMhW1Qm ...

  10. [问题解决]Deepin环境变量设置无效解决

    将环境变量的设置放在这里:  gedit ~/.bashrc 详见参考: linux下如何设置环境变量PATH : http://blog.csdn.net/witsmakemen/article/d ...