对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 相关文章推荐
Dojo之路:如何利用Dojo实现Drag and Drop效果
Apr 10 Javascript
JQuery跨Iframe选择实现代码
Aug 19 Javascript
Juery解决tablesorter中文排序和字符范围的方法
May 06 Javascript
javascript实现控制的多级下拉菜单
Jul 05 Javascript
AngularJS中transclude用法详解
Nov 03 Javascript
JS字符串长度判断,超出进行自动截取的实例(支持中文)
Mar 06 Javascript
基于Node.js模板引擎教程-jade速学与实战1
Sep 17 Javascript
JS实现的计数排序与基数排序算法示例
Dec 04 Javascript
vue 中 命名视图的用法实例详解
Aug 14 Javascript
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
Aug 12 Javascript
JS访问对象两种方式区别解析
Aug 29 Javascript
js+canvas实现转盘效果(两个版本)
Sep 13 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
东芝TOSHIBA RP-F11电路分析
2021/03/02 无线电
在WordPress中使用PHP脚本来判断访客来自什么国家
2015/12/10 PHP
PHP反射API示例分享
2016/10/08 PHP
php封装json通信接口详解及实例
2017/03/07 PHP
PHP封装cURL工具类与应用示例
2019/07/01 PHP
PHP数组array类常见操作示例
2020/05/15 PHP
form表单只提交数据而不进行页面跳转的解决方案
2013/09/18 Javascript
JQ获取动态加载的图片大小的正确方法分享
2013/11/08 Javascript
鼠标移到div,浮层显示明细,弹出层与div的上边距左边距重合(示例代码)
2013/12/14 Javascript
jquery实现的鼠标拖动排序Li或Table
2014/05/04 Javascript
JavaScript sub方法入门实例(把字符串显示为下标)
2014/10/17 Javascript
JavaScript中的toDateString()方法使用详解
2015/06/12 Javascript
JS+CSS实现分类动态选择及移动功能效果代码
2015/10/19 Javascript
微信小程序 wxapp视图容器 view详解
2016/10/31 Javascript
js编写简单的计时器功能
2017/07/15 Javascript
JS判断微信扫码的方法
2017/08/07 Javascript
vue.js实现双击放大预览功能
2020/06/23 Javascript
node.js基础知识汇总
2020/08/25 Javascript
[48:41]VP vs VG Supermajor小组赛 B组胜者组决赛 BO3 第二场 6.2
2018/06/03 DOTA
python 远程统计文件代码分享
2015/05/14 Python
spyder常用快捷键(分享)
2017/07/19 Python
Python异常对代码运行性能的影响实例解析
2018/02/08 Python
TensorFlow打印tensor值的实现方法
2018/07/27 Python
Python 批量刷博客园访问量脚本过程解析
2019/08/30 Python
基于Python实现人脸自动戴口罩系统
2020/02/06 Python
解决阿里云邮件发送不能使用25端口问题
2020/08/07 Python
python excel和yaml文件的读取封装
2021/01/12 Python
彻底解决pip下载pytorch慢的问题方法
2021/03/01 Python
意大利灯具购物网站:Lampade.it
2018/10/18 全球购物
SOA面试题:如何在SOA中实现松耦合
2013/07/21 面试题
现金会计岗位职责
2013/12/05 职场文书
大学生通用个人自我评价
2014/04/27 职场文书
群众路线学习笔记范文
2014/11/06 职场文书
六一儿童节园长致辞
2015/07/31 职场文书
JS ES6异步解决方案
2021/04/29 Javascript
解决golang 关于全局变量的坑
2021/05/06 Golang