对Angular中单向数据流的深入理解

变更检测

Angular 中,数据是由顶部根节点流向最后的叶子节点,整个数据流是单向,构成一颗单向树。

Angular 认为所有的异步操作都有可能会引起模型的变化,引起数据模型发生变化的事件源有:

  • Events:click, mouseover, keyup ...
  • Timers:setInterval、setTimeout
  • XHRs:Ajax(GET、POST ...)

Angular 封装 Zone来拦截跟踪异步,一旦发现异步行为,Angular 就会进行变更检测。

因为数据流是单向的,组件的数据来源只能由父组件进行传入,所以 Angular 会从上到下,广度遍历检测组件,只要父组件检测完毕就能继续检测子组件。而相比 angularjs,双向、混乱的数据流方向,会导致重复变更检测重复多次,直到数据稳定,可能会导致性能问题,或者出现数据和视图处于不一致的状态,即渲染过程完成后的视图不能反映数据的实际状态。

渲染输出

当检测到数据模型变化时,组件需要重新渲染,Angular将运行它的 DOM 生成函数,该函数会生成一个新的 DOM数据结构,该结构对应于组件 View 的新版本。

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数据结构的流程。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 对Angular中单向数据流的深入理解

    变更检测 Angular 中,数据是由顶部根节点流向最后的叶子节点,整个数据流是单向,构成一颗单向树. Angular 认为所有的异步操作都有可能会引起模型的变化,引起数据模型发生变化的事件源有: Events:click, mouseover, keyup ... Timers:setInterval.setTimeout XHRs:Ajax(GET.POST ...) Angular 封装 Zone来拦截跟踪异步,一旦发现异步行为,Angular 就会进行变更检测. 因为数据流是单向的,组件

  • vue单向数据流的深入理解

    目录 官网解释 单向数据流是什么 示例 a-input原始用法 组件代码 使用场景 总结 官网解释 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行.这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解.额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值.这意味着你不应该在一个子组件内部改变 prop.如果你这样做了,Vue 会在浏览器的控制台中发出警告. 单向数

  • angular中的默认路由的理解用法详解

    目录 0.前言 1.路由的功能及原理 2.默认路由的使用 0.前言 前一段时间折腾angular的路由折腾的够呛, 这篇文章简单介绍一下自己的理解及用法. 1.路由的功能及原理 一开始并不理解路由的存在,因为学习html的时候,访问模式是下面这样子: 也就是网址会直接访问到我们的页面.那这样有不好吗?或者说有什么问题吗?一个小demo确实没有什么问题?但是设想两个情景. 情景1:在一个功能/页面的的前提下有很多子功能或者子页面.我们这个时候可能会多建一个文件夹来区分这些功能或者页面.越多的话越难

  • 深入理解Vue 单向数据流的原理

    单向数据流是什么 单向数据流指只能从一个方向来修改状态.下图是单向数据流的极简示意: 单向数据流的极简示意 与单向数据流对对应的是双向数据流(也叫双向绑定).在双向数据流中,Model(可以理解为状态的集合) 中可以修改自己或其他Model的状态, 用户的操作(如在输入框中输入内容)也可以修改状态.这使改变一个状态有可能会触发一连串的状态的变化,最后很难预测最终的状态是什么样的.使得代码变得很难调试.如下图所示: 与双向数据流比,在单向数据流中,当你需要修改状态,完全重新开始走一个修改的流程.这

  • 深入理解Angular中的依赖注入

    一.什么是依赖注入 控制反转(IoC) 控制反转的概念最早在2004年由Martin Fowler提出,是针对面向对象设计不断复杂化而提出的一种设计原则,是利用面向对象编程法则来降低应用耦合的设计模式. IoC强调的是对代码引用的控制权由调用方转移到了外部容器,在运行是通过某种方式注入进来,实现了控制反转,这大大降低了程序之间的耦合度.依赖注入是最常用的一种实现IoC的方式,另一种是依赖查找. 依赖注入(Dependency Injection) 当然,按照惯例我们应该举个例子, 哦对,我们主要

  • 浅谈对Angular中的生命周期钩子的理解

    本文介绍了Angular中的生命周期钩子的理解,分享给大家,希望对大家有所帮助 什么是生命周期钩子 简单点来说生命周期钩子就是Angular中一个组件从被创建当销毁期间的一些有意义的关键时刻.这些关键时刻在Angular中被Angular核心模块 @angular/core 暴露出来,赋予了我们在它们发生时采取行动的能力. 有哪些生命周期钩子 Angular中从一个组件的创建到销毁一个有八个生命周期钩子它们,按照先后顺序.它们分别是: ngOnChanges() ngOnInit() ngDoC

  • angular中默认路由的理解用法详解

    目录 0.前言 1.路由的功能及原理 2.默认路由的使用 0.前言 前一段时间折腾angular的路由折腾的够呛, 这篇文章简单介绍一下自己的理解及用法. 1.路由的功能及原理 一开始并不理解路由的存在,因为学习html的时候,访问模式是下面这样子: 也就是网址会直接访问到我们的页面.那这样有不好吗?或者说有什么问题吗?一个小demo确实没有什么问题?但是设想两个情景. 情景1:在一个功能/页面的的前提下有很多子功能或者子页面.我们这个时候可能会多建一个文件夹来区分这些功能或者页面.越多的话越难

  • angular中实现控制器之间传递参数的方式

    在angular中,每个controller(控制器)都会有自己的$scope,通过为这个对象添加属性赋值,就可以将数据传递给模板进行渲染,每个$scope只会在自己控制器内起作用,而有时候需要用到其他控制器中的数据,这个时候就要考虑到控制器之间参数的传递了. 1.通过$rootscope传参 首先,在angular中存在作用域的继承,继承作用域符合 JavaScript 的原型继承机制,这意味着如果我们在子作用域中访问一个父作用域中定义的属性,JavaScript 首先在子作用域中寻找该属性,

  • 基于angular中的重要指令详解($eval,$parse和$compile)

    在angular的服务中,有一些服务你不得不去了解,因为他可以说是ng的核心,而今天,我要介绍的就是ng的两个核心服务,$parse和$compile.其实这两个服务讲的人已经很多了,但是100个读者就有100个哈姆雷特,我在这里讲讲自己对于他们两个服务的理解. 大家可能会疑问,$eval呢,其实他并不是一个服务,他是scope里面的一个方法,并不能算服务,而且它也基于parse的,所以只能算是$parse的另一种写法而已,我们看一下ng源码中$eval的定义是怎样的就知道了 $eval: fu

  • 学习Angular中作用域需要注意的坑

    Angular作用域 在用angular搭建的网页应用中,作用域(scope)这个概念是贯穿其中的.在angular的视图(view)中的很多指令是会创建一个作用域的,例如 ng-app , ng-controller 等.这个作用域就是我们在写控制器构造函数时注入的 $scope (angular1.2之前的版本),他是视图模型(view model)中的一个概念.我们的数据模型(model)就是定义在作用域中的. Angular作用域的坑 用过angular的人应该都会经过一个过程,就是刚开

随机推荐