因为年后公司项目转向 Angular
架构了,所以只有暂时性的放下 Vue
和 React
相关内容,转向 Angular
方向了,俗话说得好,技多不压身,就当学习一门新的框架了,那么废话不多说,让我们从头开始,慢慢来啃 Angular
这块硬骨头吧
Angular
在 2.x
之后的版本中相较与 1.x
的版本变化很多,说其为两个不同的框架也不为过,并且在新的版本当中,提供了一个 Angular-CLI
的脚手架,用于实现自动化开发工作流程,它可以创建一个新的 Angular
应用程序,并附带以下相关工具
- 运行带有
LiveReload
支持的开发服务器,以便在开发过程中预览应用程序 - 添加功能到现有的
Angular
应用程序(提供了一系列ng xxx
相关命令) - 运行应用程序的单元测试
- 运行应用程序的端到端(
E2E
)测试 - 构建应用程序
那么就先从最基本的 Angular-CLI
生成的目录结构以及相关初始化入口文件开始
Angular-CLI 目录结构
1 | ├── e2e // ==> 端到端 |
以上就是使用 Angular-CLI
默认生成的文件结构,下面我们来梳理一下一个 Angular
应用的整体架构
整体架构
整体架构可以如下图所示
Angular
使用扩展语法编写 HTML
模版,使用组件对其进行管理,通过服务来添加应用逻辑,最后使用模块来对组件进行打包,通过引导根模块来启动应用,Angular
在浏览器中接管、展现应用的内容,根据操作指令响应用户的交互,Angular
的架构主要分为四大块
- 组件,
Angular
应用的基本构件块,可以简单的理解为一个组件就是一段带有业务逻辑和数据的HTML
- 指令,允许向
HTML
元素添加自定义行为 - 模块,模块用来将应用中不同的部分组织成一个
Angular
框架可以理解的单元(组件) - 服务,用来封装可从用的业务逻辑
而整个启动过程是通过引导模块来进行的,每个 Angular
应用至少应该有一个模块,而此模块被称为根模块(App Module
)
根模块 @NgModule 装饰器
所谓的根模块,也就是我们的 app.module.ts
文件,如下所示
1 | import { BrowserModule } from '@angular/platform-browser' |
而根模块在 Angular
程序的入口 main.ts
中被使用,也就是所谓的引导过程,Angular
通过在 main.ts
中引导 AppModule
来启动应用,但是针对不同的平台 Angular
提供了很多引导选项,默认的采用是即时(JIT
)编译器动态引导,一般多用在进行开发调试的时候
1 | // main.ts |
另一种方式是使用预编译器(AoT - Ahead-Of-Time
)进行静态引导,静态方案可以生成更小、启动更快的应用,建议优先使用它,特别是在移动设备或高延迟网络下,使用 static
选项,Angular
编译器作为构建流程的一部分提前运行,生成一组类工厂,它们的核心就是 AppModuleNgFactory
,引导预编译的 AppModuleNgFactory
的语法和动态引导 AppModule
类的方式很相似
1 | // 不把编译器发布到浏览器 |
模块化
Anagulr
应用是模块化的,被称为 NgModule
,@NgModule
是一个装饰器,装饰器其实是函数,是用来装饰函数,它可以把元数据附加到类上,NgModule
装饰器用来描述模块属性,常见的模块属性如下所示
属性 | 说明 |
---|---|
declarations |
声明本模块中拥有的视图类,Angular 有三种视图类,即组件,指令和管道 |
exports |
declarations 的子集,可用于其他模块的组件模版 |
imports |
本模块声明的组件模板需要的类所在的其他模块 |
providers |
服务的创建者,并加入到全局服务列表中,可用于应用任何部分 |
bootstrap |
指定应用的主视图(根组件),它是所有其他视图的宿主 |
这里有两个地方需要注意
exports
属性并不是必须的,因为其他组件无需导入根模块,所以根模块也不需要导出- 只有根模块才能设置
bootstrap
属性
组件
和 @NgModule
类似,@Component
为 Angular
的组件装饰器,主要属性如下
属性 | 说明 |
---|---|
selector |
CSS 选择器,它告诉 Angular 在父级 HTML 中查找 selector 中定义的标签,创建并插入该组件 |
template/templateUrl |
组件或者组件 HTML 模块的相对地址 |
providers |
组件所需服务的依赖注入提供商数组,这是在告诉 Angular 该组件的构造函数可能需要一个服务,这样组件就可以从服务中获得数据 |
在根模块的 bootstrap
属性中设定了 AppComponent
组件,说明根模块引导的为 AppComponent
组件
1 | import { Component } from '@angular/core' |
- 装饰器
@Component
将三个东西结合在了一起,selector
和HTML
模板以及CSS
样式 - 通过插值的方式保证数据进行交互和传递
- 通过修改填充的内容则可以直接影响输出
- 通过
CSS
样式直接调整显示,做到数据和显示的分离
这也就是整体 Angular
程序的启动过程,不过特别需要注意的是
当组件编写完成后还需要进行组件声明后才能使用,每个组件都必须在一个
Angular
模块而且只能在一个Angular
模块中进行声明