对Angular中单向数据流的深入理解
变更检测
Angular 中,数据是由顶部根节点流向最后的叶子节点,整个数据流是单向,构成一颗单向树。
Angular 认为所有的异步操作都有可能会引起模型的变化,引起数据模型发生变化的事件源有:
- Events:click, mouseover, keyup ...
- Timers:setInterval、setTimeout
- XHRs:Ajax(GET、POST ...)
Angular 封装 Zone来拦截跟踪异步,一旦发现异步行为,Angular 就会进行变更检测。
因为数据流是单向的,组件的数据来源只能由父组件进行传入,所以 Angular 会从上到下,广度遍历检测组件,只要父组件检测完毕就能继续检测子组件。而相比 angularjs,双向、混乱的数据流方向,会导致重复变更检测重复多次,直到数据稳定,可能会导致性能问题,或者出现数据和视图处于不一致的状态,即渲染过程完成后的视图不能反映数据的实际状态。
渲染输出
当检测到数据模型变化时,组件需要重新渲染,Angular将运行它的 DOM 生成函数,该函数会生成一个新的 DOM数据结构,该结构对应于组件 View 的新版本。
Angular 在渲染过程中,评估模板表达式并在整个组件树中调用生命周期钩子。
注意:绿色标志会多次调用
从生命调用周期来看(绿色有向线),ngAfterViewChecked 标示该组件及子组件视图输出完成。看以下一例子:
import {Component, AfterViewChecked} from '@angular/core'; import {Course} from "./course"; @Component({ selector: 'app-root', template: ` <div class="course"> <span class="description">{{course.description}}</span> </div> `}) export class AppComponent implements AfterViewChecked { course: Course = { id: 1, description: "Angular For Beginners" }; ngAfterViewChecked() { this.course.description += Math.random(); } }
上述代码会在Angular变更检测周期发生错误。组件已经完成 DOM 数据结构输出,我们还在该组件 ngAfterViewChecked() 方法中修改了数据状态。这样导致了视图渲染后,数据跟视图状态不一致。
数据从组件类流向表示它们的DOM数据结构,生成这些DOM数据结构的行为本身就不会导致数据的进一步修改。但我们在 ngAfterView 生命周期发生修改数据行为,Angular 的“单向数据流”规则禁止在一个视图已经被组合好之后再更新视图。
这意味着数据模型到视图过程是单向,不可在视图后发生数据流发生改变。
总结
从变更检测过程以及渲染输出过程中,可以总结出:
单向数据流指的是从组件树的顶部到底部渲染扫描过程中应用程序数据流转到由渲染过程生成的输出DOM数据结构的流程。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
- 一些移动 Web 前端开发上的要点记录
- Angularjs基础(十一)
- Silverlight 2 的基础XAML语法学习
- TextView显示html文件中的图片
- 继百度、阿里之后,农业也刮起人工智能风,看它们都干了些啥?
- Windows Server 2008 与 .NET Framework 的版本之间有什么关系
- asp.net mvc相关开源项目推荐
- Android监听来电和去电
- PostCSS 插件postcss-lazyimagecss:自动填写width / height 属性
- Angularjs基础(十)
- Mac 中JetBrain 系列IDE 的配置文件同步(通过Dropbox)
- 面向服务架构(SOA)和企业服务总线(ESB)
- UPS宣布加入货运区块链联盟 价值万亿的物流行业未来将无纸化?
- Android中动态更新ListView
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【每日一题】【vue2源码学习】对VUE响应式数据的理解
- ApacheCN 深度学习译文集 2020.9
- 当Docker遇到Intellij IDEA,再次解放了生产力~
- 基于NPOI的Excel导入导出类库
- 在tinycolinux32上装tinycolinux64 kernel和toolchain
- 通过链下签名授权实现更少 Gas 的 ERC20代币
- 在dbcolinux上安装cozy-light
- 在群晖docker上装elmlang可视调试编码器ellie
- Elasticsearch:inverted index,doc_values及source
- 在群晖docker上构建私有云IDE和devops构建链
- 小白学PyTorch | 14 tensorboardX可视化教程
- Apache Solr 漏洞复现
- Elasticsearch rollover API
- 重发和重定向有什么区别与重定向应用
- 为tinycolinux制作应用包