对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 相关文章推荐
一个不错的应用,用于提交获取文章内容,不推荐用
Mar 03 Javascript
两种简单实现菜单高亮显示的JS类代码
Jun 27 Javascript
JavaScript 打地鼠游戏代码说明
Oct 12 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
Jun 05 Javascript
基于jquery实现最简单的选项卡切换效果
May 08 Javascript
Google Maps基础及实例解析
Aug 06 Javascript
AngularJS实现在ng-Options加上index的解决方法
Nov 03 Javascript
解析JavaScript实现DDoS攻击原理与保护措施
Dec 26 Javascript
简单实现bootstrap选项卡效果
Feb 08 Javascript
vue实现div拖拽互换位置
Jul 29 Javascript
微信小程序从注册账号到上架(图文详解)
Jul 17 Javascript
javascript数组元素删除方法delete和splice解析
Dec 09 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实现单笔转账到支付宝功能
2018/10/09 PHP
针对PHP开发安全问题的相关总结
2019/03/22 PHP
Yii框架模拟组件调用注入示例
2019/11/11 PHP
Prototype Array对象 学习
2009/07/19 Javascript
javascript 获取select下拉列表值的代码
2009/09/07 Javascript
javascript 页面划词搜索JS
2009/09/28 Javascript
基于jquery的实现简单的表格中增加或删除下一行
2010/08/01 Javascript
JQuery在页面中添加和除移DOM示例代码
2013/06/24 Javascript
用js读、写、删除Cookie代码续篇
2014/12/03 Javascript
jQuery实现类似标签风格的导航菜单效果代码
2015/08/25 Javascript
解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
2015/12/03 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
vue.js todolist实现代码
2017/10/29 Javascript
vue-cli 默认路由再子路由选中下的选中状态问题及解决代码
2018/09/06 Javascript
Python中Iterator迭代器的使用杂谈
2016/06/20 Python
浅谈Python 字符串格式化输出(format/printf)
2016/07/21 Python
Python排序搜索基本算法之选择排序实例分析
2017/12/09 Python
python安装numpy和pandas的方法步骤
2019/05/27 Python
python3的print()函数的用法图文讲解
2019/07/16 Python
Python Multiprocessing多进程 使用tqdm显示进度条的实现
2019/08/13 Python
用python生成与调用cntk模型代码演示方法
2019/08/26 Python
Pyqt5自适应布局实例
2019/12/13 Python
python实现局域网内实时通信代码
2019/12/22 Python
Tensorflow tensor 数学运算和逻辑运算方式
2020/06/30 Python
Python pandas对excel的操作实现示例
2020/07/21 Python
python Cartopy的基础使用详解
2020/11/01 Python
幼儿园大班新学期寄语
2014/01/18 职场文书
总经理任命书范本
2014/06/05 职场文书
企业安全生产月活动总结
2014/07/05 职场文书
业务员工作态度散漫检讨书
2014/11/02 职场文书
2015年保洁工作总结范文
2015/04/28 职场文书
千与千寻观后感
2015/06/04 职场文书
解决Golang中ResponseWriter的一个坑
2021/04/27 Golang
MySQL中的布尔值,怎么存储false或true
2021/06/04 MySQL
嵌入式Redis服务器在Spring Boot测试中的使用教程
2021/07/21 Redis
vue项目如何打包之项目打包优化(让打包的js文件变小)
2022/04/30 Vue.js