对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 相关文章推荐
jQuery EasyUI API 中文文档 - Pagination分页
Sep 29 Javascript
js unicode 编码解析关于数据转换为中文的两种方法
Apr 21 Javascript
JavaScript框架是什么?怎样才能叫做框架?
Jul 01 Javascript
HTML5实现留言和回复页面样式
Jul 22 Javascript
利用HTML5的画布Canvas实现刮刮卡效果
Sep 06 Javascript
javaScript数组迭代方法详解
Apr 14 Javascript
第一次接触神奇的Bootstrap
Oct 14 Javascript
详解用vue.js和laravel实现微信授权登陆
Jun 23 Javascript
vue+node+webpack环境搭建教程
Nov 05 Javascript
解决layui前端框架 form表单,table表等内置控件不显示的问题
Aug 19 Javascript
解决vue-cli项目打包出现空白页和路径错误的问题
Sep 04 Javascript
微信小程序封装分享与分销功能过程解析
Aug 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
玛琪朵 Macchiato
2021/03/03 咖啡文化
PHP实现将视频转成MP4并获取视频预览图的方法
2015/03/12 PHP
PHP验证码类ValidateCode解析
2017/01/07 PHP
给大家分享几个常用的PHP函数
2017/01/15 PHP
php xhprof使用实例详解
2019/04/15 PHP
javascript中parentNode,childNodes,children的应用详解
2013/12/17 Javascript
nodejs 实现模拟form表单上传文件
2014/07/14 NodeJs
浅谈javascript 迭代方法
2015/01/21 Javascript
jQuery代码实现发展历程时间轴特效
2015/07/30 Javascript
jquery中cookie用法实例详解(获取,存储,删除等)
2016/01/04 Javascript
nodejs实现bigpipe异步加载页面方案
2016/01/26 NodeJs
nodejs操作mongodb的填删改查模块的制作及引入实例
2018/01/02 NodeJs
微信小程序实现刷脸登录
2018/05/25 Javascript
javascript将扁平的数据转为树形结构的高效率算法
2020/02/27 Javascript
[01:00:30]TFT vs VGJ.T Supermajor 败者组 BO3 第一场 6.5
2018/06/06 DOTA
[42:11]TNC vs Pain 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python实现简单HTML表格解析的方法
2015/06/15 Python
Python调用C++程序的方法详解
2017/01/24 Python
Python中pow()和math.pow()函数用法示例
2018/02/11 Python
Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例
2018/07/18 Python
Django模型序列化返回自然主键值示例代码
2019/06/12 Python
梅尔倒谱系数(MFCC)实现
2019/06/19 Python
Win10系统下安装labelme及json文件批量转化方法
2019/07/30 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
Python 代码调试技巧示例代码
2020/08/11 Python
详解查看Python解释器路径的两种方式
2020/10/15 Python
使用CSS3美化HTML表单的技巧演示
2016/05/17 HTML / CSS
Html5移动端获奖无缝滚动动画实现示例
2018/06/25 HTML / CSS
美国折衷生活方式品牌:Robert Graham
2018/07/13 全球购物
英国蜡烛、蜡烛配件和家居香氛购买网站:Yankee Candle
2018/12/12 全球购物
Yahoo-PHP面试题2
2014/12/06 面试题
医院辞职信范文
2014/01/17 职场文书
打造完美自荐信
2014/01/24 职场文书
2014年小学元旦活动方案
2014/02/12 职场文书
2015双创工作总结
2015/07/24 职场文书
自定义函数实现单词排序并运用于PostgreSQL(实现代码)
2021/04/22 PostgreSQL