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 ...
随机推荐
- STM32 精确输出PWM脉冲数控制电机(转)
STM32 精确输出PWM脉冲数控制电机 发脉冲两种目的1)速度控制2)位置控制 速度控制目的和模拟量一样,没有什么需要关注的地方发送脉冲方式为PWM,速率稳定而且资源占用少 stm32位置控制需要获 ...
- WKWebView简单使用
#import <WebKit/WebKit.h> @interface SchoolOverviewsViewController ()<WKUIDelegate,WKNaviga ...
- Jmeter-提取Json数据进行关联
1:Json后置处理器提取结果作为下一个sampler的传入参数 1.1:[线程组]->[简单控制器]->[HTTP sampler]->[Beanshell后置取样器]-> ...
- Codeforces Round #497 (Div. 2)B. Turn the Rectangles
Bryce1010模板 http://codeforces.com/contest/1008/problems #include <bits/stdc++.h> using namespa ...
- SpringMVC-Handler-Return Values返回值
Handler-Return Values返回值 支持的返回类型列表 Same in Spring WebFlux The table below shows supported controller ...
- python入门之冒泡排序
原理: (白话描述)一列数,从左到右,依次两两比较,若左边的数大于右边的数,则两数交换,始终保持比较后左边的数小于右边的数,这样从第一个到最后一个数全部比较一次就会把这列数中的最大值排到最后(最右边) ...
- PHP知识点总结3
PHP 函数 PHP 的真正威力源自于它的函数. 在 PHP 中,提供了超过 1000 个内建的函数. <html> <body> <?php function writ ...
- 关于Winform控件调用插入点(光标)的用法
我们自定义控件中可能会有一些光标的使用,比如插入文字和图片提示,下面是调用WIN32 API的光标用法 Winform控件调用插入点的用法 // 导入处理光标的 Windows 32 位 API // ...
- js js弹出框、对话框、提示框、弹窗总结
js弹出框.对话框.提示框.弹窗总结 一.JS的三种最常见的对话框 //====================== JS最常用三种弹出对话框 ======================== //弹 ...
- I/O————File对象
File文件对象 文件和文件夹都是用File代表 创建一个文件对象,(并不会有真正的文件或文件夹被创建) File f1 = new File("d:/lolfilder"); S ...