对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 相关文章推荐
Mootools 1.2教程 类(一)
Sep 15 Javascript
javascript 面向对象全新理练之原型继承
Dec 03 Javascript
JS 有名函数表达式全面解析
Mar 19 Javascript
ASP.NET MVC中EasyUI的datagrid跨域调用实现代码
Mar 14 Javascript
JavaScript建立一个语法高亮输入框实现思路
Feb 26 Javascript
JS获取URL中的参数数据
Dec 05 Javascript
jQuery中Dom的基本操作小结
Jan 23 Javascript
javascript发送短信验证码实现代码
Nov 12 Javascript
jQuery插件EasyUI获取当前Tab中iframe窗体对象的方法
Aug 05 Javascript
浅谈struts1 &amp; jquery form 文件异步上传
May 25 jQuery
ExtJs使用自定义插件动态保存表头配置(隐藏或显示)
Sep 25 Javascript
JavaScript交换变量常用4种方法解析
Sep 02 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下打开phpMyAdmin出现403错误的问题解决方法
2013/05/23 PHP
解析mysql left( right ) join使用on与where筛选的差异
2013/06/18 PHP
php防止SQL注入详解及防范
2013/11/12 PHP
PHP简单装饰器模式实现与用法示例
2017/06/22 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
基于jquery的自定义鼠标提示效果 jquery.toolTip
2010/11/14 Javascript
JavaScript高级程序设计(第3版)学习笔记11 内建js对象
2012/10/11 Javascript
获取客户端网卡MAC地址和IP地址实现JS代码
2013/03/17 Javascript
JS分页控件 可用于无刷新分页
2013/07/23 Javascript
js加载之使用DOM方法动态加载Javascript文件
2013/11/08 Javascript
JavaScript中的Math.E属性使用详解
2015/06/12 Javascript
javascript格式化日期时间方法汇总
2015/06/19 Javascript
javascript中数组方法汇总
2015/07/07 Javascript
再次谈论Javascript中的this
2016/06/23 Javascript
nuxt框架中路由鉴权之Koa和Session的用法
2018/05/09 Javascript
AngularJS实现的base64编码与解码功能示例
2018/05/17 Javascript
微信小程序开发的基本流程步骤
2019/01/31 Javascript
微信小程序自定义组件传值 页面和组件相互传数据操作示例
2019/05/05 Javascript
layui添加动态菜单与选项卡
2019/07/26 Javascript
Vue路由模块化配置的完整步骤
2019/08/14 Javascript
vue实现手机端省市区区域选择
2019/09/27 Javascript
python 多进程通信模块的简单实现
2014/02/20 Python
python改变日志(logging)存放位置的示例
2014/03/27 Python
python 字典(dict)按键和值排序
2016/06/28 Python
python抓取搜狗微信公众号文章
2019/04/01 Python
django自带调试服务器的使用详解
2019/08/29 Python
CSS3 icon font完全指南(CSS3 font 会取代icon图标)
2013/01/06 HTML / CSS
阿迪达斯香港官网:adidas香港
2019/11/09 全球购物
Jar包的作用是什么
2014/03/30 面试题
团结演讲稿范文
2014/05/23 职场文书
学校献爱心活动总结
2014/07/08 职场文书
党的作风建设心得体会
2014/10/22 职场文书
优秀党员个人总结
2015/02/14 职场文书
奖励通知
2015/04/22 职场文书
新闻稿件写作技巧
2015/07/18 职场文书
MySQL之高可用集群部署及故障切换实现
2021/04/22 MySQL