源码角度理解 Angular 变更检测

声明

本文作为 Angular 变更检测原理源码级的探索文章,涉及到了 View 、Zone.js 这两个重要问题。建议对此不熟悉的读者翻看我之前的两篇文章:Angular 中 View 的那些事儿Zone.js 入门

前言

Angular 作为一个 MVVM 框架,由 View Model 层与 View 层配合实现数据绑定。具体来说,在 Angular 中,NgZone(Zone.js 的封装)负责劫持了所有的 Web 事件和异步函数(比如定时器等),并在其回调函数执行完毕后通知 Angular 对 View 树进行变更检测操作。变更检测通过比对 View 中绑定数据在事件前后的变化,来决定是否需要通过操作 DOM 的方式来更改页面上的绑定数据。一个简单的流程如下图所示。在下一节,我会从源码角度分析变更检测的原理。

继续阅读源码角度理解 Angular 变更检测

Angular 中 View 的那些事儿

Photo by Toa Heftiba on Unsplash

声明

Angular 视图是个神奇的存在,因为在官方文档中你很难寻觅到 View 这的身影,但是阅读源码,你却会发现 View 是 Angular 中举足轻重的一个概念。本文通过 MVVM 概念入手,讲解 View 在 MVVM 中的作用,以及在源码级别,Angular 如何实现它。

MVVM 架构

Angular 作为一套 MVVM 框架,通过 View 层来实现页面元素与数据的绑定,并由 ViewModel 层自动将数据的变化反应到视图上。

其中 ViewModel 层是由变化检测机制与 View 层配合实现的。而 View 作为一个中间结构,通过关联页面元素与数据让 ViewModel 层在变更检测阶段,对页面上绑定的数据进行更新。

阅读更多

Angular 动态创建嵌入式视图

Photo by James Coleman on Unsplash

声明

本篇为 Angular 中相对高级的教程,涉及到了结构性指令、生命周期重要概念。建议这块不熟悉的读者可以看看 Angular 结构型指令 NgIf 原理 ,这篇文章中我结合源码对 Angular 指令中的黑魔法做了解析。

视图

Angular 中视图是一个重要的概念。从源码角度来看,Angular 中的视图是包含页面结点(DOM)与在此之上的绑定(数据)的结构体,通过视图 Angular 将变量与页面结点进行关联,从而可以在执行变更检测等操作时实现控制层数据与页面结点的联动,这也也是绑定 (binding)这一术语的由来。

继续阅读Angular 动态创建嵌入式视图

Zone.js 源码初探

声明

本文假设读者已经了解 Zone.js 的基本用法,明白 Zone.js 需要解决的问题。需要学习或复习的读者可以参看我的另一篇文章 Zone.js 入门

初识 Zone.js

Angular 仓库下的那个 Zone.js 中的例子有点小小的问题。因此这边,我 fork了一份原作者的仓库进行学习研究。Zone.js 本身是由 TypeScript 写就,通过Gulp + Rollup 的方式进行构建,这块应用比较复杂,这里我们只需重点关注 dist 文件夹下最终编译合并后的 zone.js 。这份代码对应了源码中多个不同的 TS 文件,我们可以参考一个简单的例子,来共同探寻 Zone.js 源代码的秘密。

继续阅读Zone.js 源码初探

Zone.js 入门

Photo by Sebastian Unrau on Unsplash

声明

本文是 Zone.js 源码解析的前置章节。在这里,我会简单介绍 Zone.js 要解决的问题、简单原理以及基本用法。我相信这是我们探索源码前的必备工作。假如您已经有了 Zone.js 的相关应用经验,就可以轻松加愉快的直接略过本章,和我一起来探索 Zone.js 的具体实现。

继续阅读Zone.js 入门

Angular Resolver 教程

Photo by Kristine Weilert on Unsplash

声明

本教程是 Angular 路由快速教程的后续章节。假设您已经拥有了一些 Angular 相关的基础路由知识,了解了 Angular 路由模块常见路由组件以及路由匹配的基本方法,尚不清楚的同学建议复习一下路由相关知识

Resolver —— 路由的新机制

在很多时候,我们会在组件初始化的时候(ngOnInit 消息钩子)中预先抓取数据。但是假如数据抓取耗时较长,会导致在组件渲染的时候数据还没拿到渲染的数据(多数情况会在控制台报错)。为了避免这种情况,就要用到 Resolver 在路由到组件之前做数据的预抓取。

相比于直接在组件中注入服务,Resolver 可以将数据抓取与其他业务逻辑分离开来,更加利于项目的维护和扩展。这种做法也被称为遵循 “单一职责原则(single responsibility principle )”。

Angular 配置一个 Resolver 也非常简单。只需在路由匹配表中,为某一条路由的 resolve 属性指定一个满足某种格式的服务,就可以轻松实现预抓取。

继续阅读Angular Resolver 教程