Angular 学习之路 04 - 架构

在见识过 Angular 项目结构之后,我们对 Angular 有了一个大致的了解。现在,我们将整体了解下 Angular 的架构以及各个概念,方便以后的学习。

Angular 架构

Angular 的核心是组件 component。前面我们已经看到,一个 Angular 应用就是一棵以根组件(通常称为AppComponent)为根的组件树。我们向这棵树添加更多组件,来构建我们的应用。

下面我们以著名的 todomvc 为例,来看一下一个典型的 Angular 应用的组成部分。

这是一个简单的任务清单应用。我们可以在上方的输入框新增任务,可以通过每个任务前面的按钮完成任务,可以使用下面的按钮切换任务。

从 Angular 的视角来看,这个应用由很多组件构成。我们把应用想象成下面图片所示:整个应用是一个TodoComponent,输入框是TodoCreatorComponent,任务列表是TodoListComponent,列表中每一行都是一个TodoItemComponent,最下面是FooterComponent

回忆一下上一章的内容。

一个组件就是一个普通的 TypeScript 类,使用@Component修饰器修饰。修饰器提供了这个类的元数据以及如何渲染的模板。类的数据通过数据绑定 data binding 显示在模板中。模板使用特殊语法使用类的数据(也就是前面我们看到的{{}})。

除了组件,我们还有额外的结构来支撑整个系统。服务 service 就是其中之一。顾名思义,服务就是用来给组件提供服务的。组件需要的数据、各种日志、业务逻辑、HTTP 请求等,都通过服务实现。Angular 提供了很多服务,用于 HTTP 请求、路由跳转等,我们也会自定义很多自己的服务,用来实现业务相关的逻辑。

当组件需要使用服务的时候,并不需要自己创建服务,而是向 Angular 的注入器 Injector 发出请求,要求 Angular 提供自己需要的服务。注入器得到请求之后,会自动查找看有没有这个服务注册过,如果有,则将服务的实例返回给组件。这一过程就是依赖注入 dependency injection

另外重要的还有指令 directive。指令分为结构指令和属性指令。前者用于修改 DOM 结构,例如循环、判断等;后者用于给某个元素添加属性。我们通过指令直接修改 DOM。

Angular Module

前面我们已经见识到 Angular 应用由很多部分组成:组件、服务、指令等。随着应用规模的增大,这些部分会越来越多。Angular 使用模块 module 来组织这些组件、服务和指令。当创建组件、服务或指令时,我们将它们添加到一个模块。Angular 模块也被称作 ngModule。

Angular 模块用于组织 Angular 代码结构。一个 Angular 应用由多个 Angular 模块组成。一般而言,一个模块负责应用的一个功能。

JavaScript Module(ES2015)

Angular 模块和 JavaScript 模块不同。Angular 模块仅用于 Angular 项目;JavaScript 模块则是 JavaScript 的语言标准,适用于所有 JavaScript 项目。ES2015 标准定义了 JavaScript 模块。在 ES2015 标准中,一个 JavaScript 文件就是一个 JavaScript 模块,一个 JavaScript 模块只包含一个 JavaScript 文件。

JavaScript 模块定义了变量、函数和类的作用域。这些数据的作用域限于模块内部,在模块外部并不可见。这就是说,如果一个模块没有公共的函数或属性,这个模块就没有什么用处,因为模块外没有办法使用模块中的任何代码。模块使用export语句将其函数或属性变成公共的。而想要使用另外的模块的公共函数的模块,则需要使用import语句导入。

尽管 Angular 的最常用开发语言是 TypeScript,但 TypeScript 仅作为 JavaScript 的前置处理,依然使用了 JavaScript 模块。我们的组件、服务、指令都在 JavaScript 模块中(因为一个文件就是一个 JavaScript 模块):一个组件就是一个 JavaScript 模块,一个服务也是一个 JavaScript 模块。最后,我们使用 Angular 模块将这些打包在一起。

了解了这些之后,回忆一下上一章我们看到的那些代码就会明白,为什么每个文件头部都有一堆import语句,为什么每个class都要使用export修饰。

现在我们简单介绍了 Angular 的部分概念。下一章我们将详细介绍一个 Angular 项目是如何引导的:当你在浏览器地址栏输入一个 Angular 应用的地址直到 Angular 把整个页面渲染出来这个过程究竟发生了什么。

Leave a Reply