对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 相关文章推荐
[原创]站长必须要知道的javascript广告代码
May 30 Javascript
jquery.validate使用攻略 第三部
Jul 01 Javascript
一些实用的jQuery代码片段收集
Jul 12 Javascript
js实现屏幕自适应局部代码分享
Jan 30 Javascript
基于javascript实现动态时钟效果
Aug 18 Javascript
基于JavaScript实现复选框的全选和取消全选
Feb 09 Javascript
JS仿JQuery选择器功能
Mar 08 Javascript
在一般处理程序(ashx)中弹出js提示语
Aug 16 Javascript
parabola.js抛物线与加入购物车效果的示例代码
Oct 25 Javascript
angular4 JavaScript内存溢出问题
Mar 06 Javascript
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
Jan 19 Javascript
js实现课堂随机点名系统
Nov 21 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读取IMAP邮件
2006/10/09 PHP
PHP中替换键名的简易方法示例详解
2014/01/07 PHP
漂亮的thinkphp 跳转页封装示例
2019/10/16 PHP
js 发个判断字符串是否为符合标准的函数
2009/04/27 Javascript
javascript 原型继承介绍
2011/08/30 Javascript
浅谈javascript中的作用域
2012/04/07 Javascript
Jquery显示、隐藏元素以及添加删除样式
2013/08/09 Javascript
jQuery实现异步获取json数据的2种方式
2014/08/29 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
2014/11/28 Javascript
jquery实现带缩略图的全屏图片画廊效果实例
2015/06/25 Javascript
JavaScript数组去重的3种方法和代码实例
2015/07/01 Javascript
前端设计师们最常用的JS代码汇总
2016/09/25 Javascript
js实现界面向原生界面发消息并跳转功能
2016/11/22 Javascript
Vue开发中整合axios的文件整理
2017/04/29 Javascript
Node.JS文件系统解析实例详解
2017/05/15 Javascript
vue脚手架及vue-router基本使用
2018/04/09 Javascript
Vue之mixin全局的用法详解
2018/08/22 Javascript
vue项目引入字体.ttf的方法
2018/09/28 Javascript
Vue跨域请求问题解决方案过程解析
2020/08/07 Javascript
[23:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
windows环境下tensorflow安装过程详解
2018/03/30 Python
浅谈pyqt5在QMainWindow中布局的问题
2019/06/21 Python
使用 Python 合并多个格式一致的 Excel 文件(推荐)
2019/12/09 Python
django使用F方法更新一个对象多个对象字段的实现
2020/03/28 Python
通过实例解析python and和or使用方法
2020/11/14 Python
CSS3绘制不规则图形的一些方法示例
2015/11/07 HTML / CSS
HTML5 在canvas中绘制文本附效果图
2014/06/23 HTML / CSS
NET程序员上机面试题
2015/05/23 面试题
一套C#面试题
2013/10/09 面试题
下列程序在32位linux或unix中的结果是什么
2014/03/25 面试题
办公室员工岗位工作职责
2014/03/10 职场文书
学生会部长竞聘书
2014/03/31 职场文书
小学生家长寄语
2014/04/02 职场文书
2016党员党章学习心得体会
2016/01/14 职场文书
python实现web邮箱扫描的示例(附源码)
2021/03/30 Python
win server2012 r2服务器共享文件夹如何设置
2022/06/21 Servers