对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 18 Javascript
JavaScript实现GriwView单列全选(自写代码)
May 13 Javascript
js实现简单的星级选择器提交效果适用于评论等
Oct 18 Javascript
在JavaScript中重写jQuery对象的方法实例教程
Aug 25 Javascript
jquery使用each方法遍历json格式数据实例
May 18 Javascript
详解BootStrap中Affix控件的使用及保持布局的美观的方法
Jul 08 Javascript
关于两个jQuery(js)特效冲突的bug的解决办法
Sep 04 Javascript
JavaScript实现图像模糊化的方法实例
Jan 15 Javascript
js仿淘宝商品放大预览功能
Mar 15 Javascript
微信小程序实现手势图案锁屏功能
Jan 30 Javascript
node中的session的具体使用
Sep 14 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
Aug 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下MYSQL limit的优化
2008/01/10 PHP
PHP生成不重复标识符的方法
2014/11/21 PHP
php页面缓存方法小结
2015/01/10 PHP
php使用iconv中文截断问题的解决方法
2015/02/11 PHP
php开发中的页面跳转方法总结
2015/04/26 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
用jQuery扩展自写的 UI导航
2010/01/13 Javascript
JS将表单导出成EXCEL的实例代码
2013/11/11 Javascript
js实现仿京东2级菜单效果(带延时功能)
2015/08/27 Javascript
jQuery检测滚动条是否到达底部
2015/12/15 Javascript
JavaScript几种数组去掉重复值的方法推荐
2016/04/12 Javascript
详谈JS中实现种子随机数及作用
2016/07/19 Javascript
JS中的==运算: [''] == false —&gt;true
2016/07/24 Javascript
详解JavaScript权威指南之对象
2016/09/27 Javascript
深入理解Angularjs向指令传递数据双向绑定机制
2016/12/31 Javascript
View.post() 不靠谱的地方你知道多少
2017/08/29 Javascript
node作为中间服务层如何发送请求(发送请求的实现方法详解)
2018/01/02 Javascript
使用vue-aplayer插件时出现的问题的解决
2018/03/02 Javascript
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
[24:42]VP vs TNC Supermajor小组赛B组 BO3 第三场 6.2
2018/06/03 DOTA
python根据经纬度计算距离示例
2014/02/16 Python
python通过正则查找微博@(at)用户的方法
2015/03/13 Python
Python并发编程协程(Coroutine)之Gevent详解
2017/12/27 Python
python 将对象设置为可迭代的两种实现方法
2019/01/21 Python
python读取图片的方式,以及将图片以三维数组的形式输出方法
2019/07/03 Python
分享一个python的aes加密代码
2020/12/22 Python
Mio Skincare美国官网:身体紧致及孕期身体护理
2017/03/05 全球购物
枚举和一组预处理的#define有什么不同
2016/09/21 面试题
简述安装Slackware Linux系统的过程
2012/05/08 面试题
2014年应届大学生毕业自我鉴定
2014/01/31 职场文书
社区活动总结报告
2014/05/05 职场文书
家长会欢迎标语
2014/06/24 职场文书
一份恶作剧的检讨书
2014/09/13 职场文书
乡领导班子四风问题对照检查材料
2014/09/25 职场文书
2014年中班下学期工作总结
2014/12/11 职场文书
房屋质量投诉书
2015/07/02 职场文书