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 层在变更检测阶段,对页面上绑定的数据进行更新。

组件 与 View

组件和 View 的区别在于, 前者是 View 的具体实现,让开发者可以利用组件去编写一个 View。

在构建 Angular 应用的时候,其实我们已经将应用划分为一个个组件,每个组件经过 Angular 编译器编译后会构造出一个 View。Angular 依照组件之间的嵌套关系,相应地将视图构成一颗 View 树。

View 树的实现

这里我们在名为 my-app 的组件简单地增加了 <span> Hello Vue </span> 标签。 经过 Angular 编译之后就会形成一颗如下的 View 树。

Angular 会利用 View 中 nodes 属性来存放当前视图所包含的元素。若元素是一个组件,如 my-app,那么 Angular 会继续解析此组件中包含的元素。若此元素是一个普通页面元素,Angular 直接构造出 HTML 元素,并把相关对象存储在 nodes 属性中。这样不断迭代构造,直至叶子结点都是基础的 HTML 元素,结束树的构造。

这个处理逻辑在 createViewNodes execComponentViewsAction 中得到了体现。

构造页面元素

根据视图中元素类型的不同,Angular 采用了不同的方式进行构造。这个实现逻辑主要被封装在 createViewNodes 中。

对于 HTML 标签,Angular 在内部将其定义为 TypeElement 类型。此类型元素主要通过 document.createElement 这个 Web API 将元素显示在页面上。

对于标签中的文本元素,Angular 在内部将其定义为 TypeText 类型。此类型元素主要通过 document.createTextNode 方法将其构造在页面上。

递归构造组件

若是组件元素,Angular 会使用 execComponentViewsAction 对其进行递归构造,调用的仍然是 createViewNodes 方法。

总结

Angular 是一个 MVVM 框架。View 中包含了页面中的结点与绑定元素,并在 View 创建时通过createViewNodes 方法创建 View 中包含的元素结点。若元素结点本身仍然是一个 View,则继续调用 createViewNodes 方法进行迭代,直至所有的 View 创建完毕为止。

参考链接

The mechanics of DOM updates in Angular

Model–view–viewmodel

发表评论

电子邮件地址不会被公开。 必填项已用*标注