Angular框架详解之视图抽象定义
前言
作为“为大型前端项目”而设计的前端框架,angular 其实有许多值得参考和学习的设计,本系列主要用于研究这些设计和功能的实现原理。本文主要围绕 angular 中与视图有关的一些定义进行介绍。
angular 中的视图抽象
angular 版本可在不同的平台上运行:在浏览器中、在移动平台上或在 web worker 中。因此,需要特定级别的抽象来介于平台特定的 api 和框架接口之间。
angular 中通过抽象封装了不同平台的差异,并以下列引用类型的形式出现:elementref,templateref,viewref,componentref和viewcontainerref。
各抽象类视图定义
在阅读源码的时候,如果不清楚这些定义之间的区别,很容易搞混淆。所以,这里我们先来理解下它们之间的区别。
元素 elementref
elementref是最基本的抽象。如果观察它的类结构,可以看到它仅包含与其关联的本地元素:
该 api 可用于直接访问本地 dom 元素,可以比作document.getelementbyid('myid')。但 angular 并不鼓励直接使用,尽可能使用 angular 提供的模板和数据绑定。
模板 templateref
在 angular 中,模板用来定义要如何在 html 中渲染组件视图的代码。
模板通过@component()装饰器与组件类类关联起来。模板代码可以作为template属性的值用内联的方式提供,也可以通过 templateurl属性链接到一个独立的 html 文件。
用templateref对象表示的其它模板用来定义一些备用视图或内嵌视图,它们可以来自多个不同的组件。templateref是一组 dom 元素(elementref),可在整个应用程序的视图中重复使用:
就其本身而言,templateref类是一个简单的类,仅包括:
elementref属性:拥有对其宿主元素的引用
createembeddedview方法:它允许我们创建视图并将其引用作为viewref返回。
模板会把纯 html 和 angular 的数据绑定语法、指令和模板表达式组合起来。angular 的元素会插入或计算那些值,以便在页面显示出来之前修改 html 元素。
angular 中的视图
在 angular 中,视图是可显示元素的最小分组单位,它们会被同时创建和销毁。angular 哲学鼓励开发人员将 ui 视为视图的组合(而不是独立的 html 标签树)。
组件(component) 类及其关联的模板(template)定义了一个视图。具体实现上,视图由一个与该组件相关的viewref实例表示。
viewref
viewref表示一个 angular 视图:
其中,changedetectorref提供更改检测功能的基类,用于更改检测树收集所有要检查更改的视图:
两种类型的视图
angular 支持两种类型的视图:
(1) 链接到模板(template)的嵌入式视图(embeddedview)。
嵌入式视图表示视图容器中的 angular 视图。模板只是保存视图的蓝图,可以使用上述的createembeddedview方法从模板实例化视图。
(2) 链接到组件(component)的宿主视图(hostview)。
直属于某个组件的视图叫做宿主视图。
宿主视图是在动态实例化组件时创建的,可以使用componentfactoryresolver动态创建实例化一个组件。在 angular 中,每个组件都绑定到特定的注入器实例,因此在创建组件时我们将传递当前的注入器实例。
视图中各个元素的属性可以动态修改以响应用户的操作,而这些元素的结构(数量或顺序)则不能。你可以通过在它们的视图容器(viewcontainer)中插入、移动或移除内嵌视图来修改这些元素的结构。
viewcontainerref
viewcontainerref是可以将一个或多个视图附着到组件中的容器:
任何 dom 元素都可以用作视图容器,angular 不会在元素内插入视图,而是将它们附加到绑定到viewcontainer的元素之后。
通常,标记ng-container元素是标记应创建viewcontainer的位置的最佳选择。它作为注释呈现,因此不会在 dom 中引入多余的 html 元素。
通过viewcontainerref,可以用createcomponent()方法实例化组件时创建宿主视图,也可以用 createembeddedview()方法实例化templateref时创建内嵌视图。
视图容器的实例还可以包含其它视图容器,以创建层次化视图(视图树)。
视图树(view hierarchy)
在 angular 中,通常会把视图组织成一些视图树(view hierarchies)。视图树是一棵相关视图的树,它们可以作为一个整体行动,是 angular 变更检测的关键部件之一。
视图树的根视图就是组件的宿主视图。宿主视图可以是内嵌视图树的根,它被收集到了宿主组件上的一个视图容器(viewcontainerref)中。当用户在应用中导航时(比如使用路由器),视图树可以动态加载或卸载。
视图树和组件树并不是一一对应的:
- 嵌入到指定视图树上下文中的视图,也可能是其它组件的宿主视图
- 组件可能和宿主组件位于同一个ngmodule中,也可能属于其它ngmodule
组件、模板、视图与模块
在 angular 中,可以通过组件的配套模板来定义其视图。模板就是一种 html,它会告诉 angular 如何渲染该组件。
视图通常会分层次进行组织,让你能以 ui 分区或页面为单位进行修改、显示或隐藏。与组件直接关联的模板会定义该组件的宿主视图。该组件还可以定义一个带层次结构的视图,它包含一些内嵌的视图作为其它组件的宿主。
带层次结构的视图可以包含同一模块(ngmodule)中组件的视图,也可以(而且经常会)包含其它模块中定义的组件的视图。
总结
本文简单介绍了 angular 中元素、视图、模板、组件中与视图相关的一些定义,包括elementref,templateref,viewref,componentref和viewcontainerref。
其中,视图是 angular 中应用程序 ui 的基本构建块,它是一起创建和销毁的最小元素组。
viewcontainerref主要用于创建和管理内嵌视图或组件视图。组件可以通过配置模板来定义视图,与组件直接关联的模板会定义该组件的宿主视图,同时组件还可以包括内嵌视图。
到此这篇关于angular框架详解之视图抽象定义的文章就介绍到这了,更多相关angular视图抽象定义内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
参考
上一篇: AngularJS 中括号的作用详解
下一篇: 基于angular实现树形二级表格