对Angular中单向数据流的深入理解


Posted in Javascript onMarch 31, 2018

变更检测

Angular 中,数据是由顶部根节点流向最后的叶子节点,整个数据流是单向,构成一颗单向树。

对Angular中单向数据流的深入理解

Angular 认为所有的异步操作都有可能会引起模型的变化,引起数据模型发生变化的事件源有:

  • Events:click, mouseover, keyup ...
  • Timers:setInterval、setTimeout
  • XHRs:Ajax(GET、POST ...)

Angular 封装 Zone来拦截跟踪异步,一旦发现异步行为,Angular 就会进行变更检测。

因为数据流是单向的,组件的数据来源只能由父组件进行传入,所以 Angular 会从上到下,广度遍历检测组件,只要父组件检测完毕就能继续检测子组件。而相比 angularjs,双向、混乱的数据流方向,会导致重复变更检测重复多次,直到数据稳定,可能会导致性能问题,或者出现数据和视图处于不一致的状态,即渲染过程完成后的视图不能反映数据的实际状态。

渲染输出

当检测到数据模型变化时,组件需要重新渲染,Angular将运行它的 DOM 生成函数,该函数会生成一个新的 DOM数据结构,该结构对应于组件 View 的新版本。

Angular 在渲染过程中,评估模板表达式并在整个组件树中调用生命周期钩子。

注意:绿色标志会多次调用

对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数据结构的流程。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
xml 与javascript结合的问题解决方法
Mar 24 Javascript
Ext.MessageBox工具类简介
Dec 10 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
Oct 11 Javascript
node.js中的events.emitter.once方法使用说明
Dec 10 Javascript
jQuery中的pushStack实现原理和应用实例
Feb 03 Javascript
JavaScript生成带有缩进的表格代码
Jun 15 Javascript
JavaScript基于activexobject连接远程数据库SQL Server 2014的方法
Jul 12 Javascript
基于vue.js实现的分页
Mar 13 Javascript
原生JS实现简单的无缝自动轮播效果
Sep 26 Javascript
Vue 递归多级菜单的实例代码
May 05 Javascript
layer.confirm()右边按钮实现href的例子
Sep 27 Javascript
JavaScript获取URL参数的方法分享
Apr 07 Javascript
jQuery中复合选择器简单用法示例
Mar 31 #jQuery
jQuery中内容过滤器简单用法示例
Mar 31 #jQuery
jQuery中可见性过滤器简单用法示例
Mar 31 #jQuery
Postman模拟发送带token的请求方法
Mar 31 #Javascript
浅谈Postman解决token传参的问题
Mar 31 #Javascript
postman+json+springmvc测试批量添加实例
Mar 31 #Javascript
JS和Canvas实现图片的预览压缩和上传功能
Mar 30 #Javascript
You might like
编写PHP的安全策略
2006/10/09 PHP
php实现的简单压缩英文字符串的代码
2008/04/24 PHP
php下pdo的mysql事务处理用法实例
2014/12/27 PHP
PHP中应该避免使用同名变量(拆分临时变量)
2015/04/03 PHP
Yii2中如何使用modal弹窗(基本使用)
2016/05/30 PHP
如何使用Javascript正则表达式来格式化XML内容
2013/07/04 Javascript
JavaScript prototype 使用介绍
2013/08/29 Javascript
javascript获取xml节点的最大值(实现代码)
2013/12/11 Javascript
通过XMLHttpRequest和jQuery实现ajax的几种方式
2015/08/28 Javascript
原生javascript实现的ajax异步封装功能示例
2016/11/03 Javascript
详解JavaScript常量定义
2017/01/03 Javascript
详解Jquery EasyUI tree 的异步加载(遍历指定文件夹,根据文件夹内的文件生成tree)
2017/02/11 Javascript
jquery实现轮播图效果
2017/02/13 Javascript
深入理解ES6 Promise 扩展always方法
2017/09/26 Javascript
JavaScript判断输入是否为数字类型的方法总结
2017/09/28 Javascript
手把手教你使用vue-cli脚手架(图文解析)
2017/11/08 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
2017/11/28 Javascript
微信小程序开发搜索功能实现(前端+后端+数据库)
2020/03/04 Javascript
sharp.js安装过程中遇到的问题总结
2020/04/02 Javascript
Vue使用轮询定时发送请求代码
2020/08/10 Javascript
[03:49]辉夜杯现场龙骑士COSER秀情商“我喜欢芬队!”
2015/12/27 DOTA
用python实现简单EXCEL数据统计的实例
2017/01/24 Python
python简单商城购物车实例代码
2018/03/15 Python
解决pycharm运行时interpreter为空的问题
2018/10/29 Python
Pyqt5如何让QMessageBox按钮显示中文示例代码
2019/04/11 Python
python使用pandas处理excel文件转为csv文件的方法示例
2019/07/18 Python
Python3多线程版TCP端口扫描器
2019/08/31 Python
python matplotlib如何给图中的点加标签
2019/11/14 Python
python collections模块的使用
2020/10/16 Python
CSS3转换功能transform主要属性值分析及实现分享
2012/05/06 HTML / CSS
PHP笔试题
2012/02/22 面试题
培训主管的岗位职责
2013/11/23 职场文书
幼教毕业生自我鉴定
2014/01/12 职场文书
演讲稿的格式及范文
2014/08/22 职场文书
学校领导班子群众路线整改措施
2014/09/16 职场文书
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android