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. extern用法详解(转)

    1 基本解释 extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义. 另外,extern也可用来进行链接指定. 2 问题:ext ...

  2. rn-splash-screen 启动页 ios

    1.删除iOS工程文件夹下的 LaunchScreen.xib 文件 2. 3.  如果第4步不一样的样式,可以重新走这个图片的步骤就行 4.进入iOS工程的AppDelegate.m中做如下修改: ...

  3. kuangbin大佬的高斯消元模板

    dalao解释的博客 #include <bits/stdc++.h> using namespace std; ; int a[MAXN][MAXN];//增广矩阵 int x[MAXN ...

  4. JMeter提取和重用作为变量 - 具有更多提取器

    这是我们最受欢迎的博文,我们添加了更多提取器.这篇文章解释了如何使用正则表达式提取器从第一个请求的响应中提取密钥,并将提取的密钥用于后续请求.我们称之为JMeter Extract并重复使用. 现在您 ...

  5. dubbo属性配置

    一.覆盖策略 JVM启动-D参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口.XML次之,如果在XML中有配置,则dubbo.properties中的相应配置项无效.P ...

  6. Excel2Json记录

    1.有关配置的读取 import configparser import codecs #配置文件格式[config] #自定义的配置key=valuekey2=value2 读取配置 conf = ...

  7. 禁用和关闭ECSHOP缓存

    ECSHOP的缓存机制从一定程度上可以减少ECSHOP反复读取数据库的几率,从而一定程度上降低服务器负担,提高访问速度. 但是启用缓存机制,对一些新手站长也有不利的地方.我就遇到很多新手站长经常问,我 ...

  8. AJPFX关于Collection接口的总结

    ###15Collection-List-ArrayList/LinkedList/*  * Collection接口中的方法* A:添加功能*                 boolean add ...

  9. wine使用

    wineqq 不能输入问题winecfg在 wine 设置里,选择函数库添加 riched20, 就行了(原装领先于内建) wineqq 可以输入不能输入中文问题原因:fictx组件缺失 搜狗输入法没 ...

  10. Objective-C Data Encapsulation

    All Objective-C programs are composed of the following two fundamental elements: Program statements ...