策略
- 在于质量,不在于速度。
- 一点点的系统推进,状态不好换其他的,不想看换其他的……
- 做好系统性的笔记,做到心中有大纲的地步。
如何开始一个项目?
对于react项目而言,fackbook出了一个create-react-app包,可以快速的搭建出一个大型项目的框架。在个人经验中,是用webpack模块化打包工具+express/webpack-dev-serve启动本地服来自行搭建开发环境的。后续会整理一片文章。
对于angular4,是用angular cli这个命令行工具来初始化一个项目的。
1 | //全局安装angular cli |
核心知识
架构
Angular中有一些重要的概念,在之前的版本中也是存在的,比如模块、组件、服务、指令、依赖注入等,接下来就先学习下这些重要概念在ng4是什么样子的存在。
主要构造/重要概念
- 模块 module
- 组件 component
- 模版 template
- 元数据 metadata
- 数据绑定 data-binding
- 指令 directive
- 服务 service
- 依赖注入 dependency injection
各个构造块之间的关联
先占位。
模块
NgModule 用于描述应用的各个部分如何组织在一起。 每个应用又至少一个 Angular 模块,根模块就是你用来启动此应用的模块。 按照惯例,它通常命名为 AppModule。
从根模块出来,来看看ngModule的metadata。
元数据解析
1 | //根模块 |
元数据对象分析:
declarations数组:
- 告诉angular哪些组件是属于该模块。整个项目中所有定义的组件都要放在这个数组中好了,每个组件只能声明在一个NgModule中。
- 治接受可声明的对象,比如组件、指令或者管道。再次强调一个可声明对象只能在一个ngModule中声明。
每个可声明对象都只能属于一个模块,所以只能把它声明在一个 @NgModule中。当你需要在其它模块中使用它时,就要在那里导入包含这个可声明对象的模块。
imports数组:
- 告诉angular该模块想正常工作,还需要哪些模块。
- 导入其它模块,这样可以用到被导入的模块中声明的组件、指令等。
- 导入的数组项只能是@NgModule模块。
组件的模板中可以引用在当前模块中声明的或从其它模块中导入的组件、指令、管道。
providers
- 该应用需要的服务,服务的创建者。
- 在根模块中providers时,服务是全应用范围的。服务的创建者,并加入到全局服务列表中,可用于应用任何部分
- 在特性模块或者惰性加载时,服务是范围化的。
bootstrap数组
- 指定应用的主视图(根节点)。
- 只有根模块才需要设置这个参数。
模块究竟是什么?
下面主要是学习官网啦!
简介
NgModules 用于配置注入器和编译器,并帮你把那些相关的东西组织在一起。
下面这句话逼格很高啊:
Angular 模块把组件、指令和管道打包成内聚的功能块,每个模块聚焦于一个特性区域、业务领域、工作流或通用工具。
- 带有@NgModule装饰器的类。
- 参数是一个元数据对象,用于描述编译模版的方法&在运行时创建注入器。
- 声明某些组件、指令和管道属于这个模块,declarations数组。
- 公开其中的部分组件、指令和管道,以便其它模块中的组件模板中可以使用它们,exports。
- 导入其它带有组件、指令和管道的模块,这些模块中的元件都是本模块所需的, imports。
- 把一些服务商添加到应用的依赖注入器中,providers数组。
常用模块
整理下常见的NgModule&作用。
模块名 | 来源 | 作用 |
---|---|---|
BrowserModule | @angular/platform-browser | 让应用可以在浏览器中应用,这个需要在根模块中导入 |
CommonModule | @angular/common | 使用内置的指令,比如NgIf、NgFor |
FormsModule | @angular/forms | 用于构建模版驱动表单(NgModule) |
ReactiveFormsModule | @angular/forms | 用于构建响应式表单 |
RouterModule | @angular/router | 使用路由功能 |
HttpClientmodule | @angular/common/http | 异步请求数据时需要用到 |
1 | //导入模块的方式 |
入口组件 entryComponents
两种类型:
- 引导用的根组件,引导过程中把它加载到DOM中。
- 在路由定义中指定的组件,动态加载。
通常情况下,对于以上两种类型的入口组件,angular会自动识别,所以不需要显式的去设置这个数组。编译起只会为从入口组件中直接或者间接访问到的组件生成代码。
- 即使在declarations数组中声明了,但是没有用到的,编译器不会声称代码。
- 导入的库中,没有用到的模块也不会生成代码。
特性模块&diy模块
特性模块提供了聚焦于特定应用需求的一组功能,抽离中一个通用的逻辑处理块。
1 | //创建module,根目录下命令行操作。 |
来来来,如何来创建一个特性模块。
1.第一步 创建module1
ng generate module CustomModule
这样就在app的目录下新建了一个custom-module的文件夹和对应的module.js。
2.第二步 创建component1
ng generate component custom-module/TestComponent
则会在custom-module中创建一个test-component的文件夹,里面会创建组件的模版、样式、定义和单元测试的文件。
3.第三步 在特性模块中将根模块需要用到的组件exports出去。1
2
3
4
5
6
7
8
9
10
11
12
13
14import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TestComponentComponent } from './test-component/test-component.component';
@NgModule({
imports: [
CommonModule
],
exports: [ //导出去
TestComponentComponent
],
declarations: [TestComponentComponent]
})
export class CustomModuleModule { }
4.第四步 在根模块中将新建的特性模块imports进来。1
2
3imports: [ //导进根模块
BrowserModule, CustomModuleModule
],
5.第五步 直接用起来就好啦。1
<app-test-component></app-test-component>
注意:在用ng generate创建模块、组件或者服务等时,会自动在后面添加Module、Component或者Service的。
服务
官网中对为什么需要服务作了一个简单的说明:
组件不应该直接获取或保存数据,它们不应该了解是否在展示假数据。 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。
创建服务
1 | ng generate service serviceName |
@Injectable()装饰器,告诉angualr这个服务本身可能拥有被注入的依赖。
1 | import { Injectable } from '@angular/core'; |
to依赖注入系统
提供到依赖注入系统中:在模块的元数据中的providers数组中添加。那么作用域是什么样的呢?
三种添加到依赖注入系统方式:根模块、惰性模块&组件。
- 在根模块中添加的话,则在整个应用中都是可用的。
- 在惰性加载模块中添加的话,惰性加载模块时会创建一个新的注入器(这是根注入器的一个子注入器),这样的话,惰性加载的话会优先选择在惰性模块中提供的服务商创建的服务实例。
任何在惰性加载模块的上下文中创建的组件(比如路由导航),都会获取该服务的局部实例,而不是应用的根注入器中的实例。而外部模块中的组件,仍然会收到来自于应用的根注入器创建的实例。
- 限定的服务也可以提供在组件的providers数组中,会限定改服务只会在该组件内可用。
使用
好,到此,这个服务就已经添加到依赖注入系统中了,那么该怎么使用呢?那就是注入。
最常见的是在组件的构造函数中注入:1
constructor(private messageService: MessageService) { }