angular学习笔记

angular学习笔记_第1张图片
angular程序架构

一、搭建Angular开发环境

安装nodejs, Angular Cli, WebStorm

先安装nodejs, 安装完成后用命令来安装Angular Cli
npm install -g @angular/cli

使用Angular Cli创建并运行Angular项目

用ng new 命令来创建一个项目,比如项目名为demo,则输入命令 ng new demo

分析Angular目录结构及Angular Cli 生成的基础代码

e2e 端到端的测试目录,用来做自动测试的
node_modules 第三方的依赖包
src 源代码目录
app 包含应用的组件和模块
assets 用来存放静态资源文件
environment 环境配置,支持多环境开发,比如开发环境和生产环境可以共用一套代码
index.html 整个应用的根文件
main.ts 整个应用的入口点
polyfills.ts 导入必要的库,使angular可以正常运行在老版本的浏览器
style.css 应用的全局样式
test.ts 做自动化测试的
tsconfig.json ts的配置文件
.editconfig webStorm的配置文件
.gitignore git的配置文件
angular-cli.json angular命令行工具的配置文件
karma.config.js karma的配置文件,用来执行自动化测试的
package.json 标准的npm工具的配置文件,当前应用使用的第三方工具包,通过npm i 来安装
protractor.conf.js 跟karma类似,也是用来做自动化测试
tslint.json 用来定义ts代码的质量检查

二、组件

定义:在angular中组件就是一个ts类,然后通过@Component装饰器装饰,装饰器里面定义了组件的元数据,包括样式,模板等等。

组件要素

必备

装饰器、模板和控制器

可选

输入属性@Input---父组件向子组件传递数据
提供器 providers---用来做依赖注入
生命周期钩子
样式表
动画---angular 提供动画包帮助我们创建组件间的动画效果
输出属性---用来在组件间共享数据

模块

用@NgModule装饰器装饰的一个ts类

元数据

declarations 只能声明组件,指令和管道
imports 引用app模块需要依赖的模块
providers 用来声明模块中提供什么服务,只能声明服务
bootstrap 声明模块的主组件

三、Angular路由

Routes

路由配置,保存着哪个URL对应展示哪个组件,以及在哪个RouterOutlet中展示

RouterOutlet

在HTML中标记路由内容呈现位置的占位符指令

Router

路由的对象,用来跳转路由,在控制器使用

RouterLink

在HTML中声明路由导航用的指令,根路由要用‘/’开头,参数是一个数组。.比如

ActivatedRoute

当前激活的路由对象,保存着路由信息。

在路由中传递参数的三种方式:

1、在查询参数中传递
 /product?id=1&name=2     =>      ActivatedRoute.queryParams[id]
2、在路由路径中传递参数
 {path:'product/:id'}     =>     /product/1     =>      ActivatedRoute.params[id]
3、在路由配置中传递参数
 {path:'product', data:[{isProd:true}]}     =>      ActivatedRoute.data[0][isProd]

参数订阅和参数快照snapshot

如果不会出现组件路由到自身的情况,则可使用参数快照来获取参数。如果会出现路由到自身的情况,则用参数订阅,也就是subcribe()方法。

为什么要这样做?
这是因为,当组件路由到自身的时候,由于组件已经被创建,那么就不会再执行ngOninit方法。而通过订阅则可以解决这个问题。

重定向路由

在用户访问特定的地址时,将其重定向到其他的地址
可用redirectTo属性

子路由

路由间的父子关系,可以无限嵌套
在用RouterLink指令时,路由要用'./'开头,表示从当前路由开始

辅助路由

路由守卫

当用户满足某种条件后才允许用户进入或离开路由。

CanActivate: 处理导航到路由的情况
CanDeActivate: 处理从当前路由离开的情况
Resolve: 在路由激活之前获取路由数据

实现:需要创建一个ts类,该类继承对应的守卫类,实现对应的方法。然后在Routes里面加入对应的属性,再把创建的类添加到providers里面。

四、依赖注入

依赖注入解决的问题

当一个方法或者类依赖其他类时,使用前需要先实例化其他类。当依赖的类多了,要实例化所有的类也是一件麻烦的事。那么能不能把实例化的工作交给其他人做, 我们只需要知道依赖哪些类,而不需要知道具体的实例方法。

依赖注入DI 和 控制反转IOC

依赖注入:侧重于描述手段,如何来实现控制反转的手段
控制反转:侧重于描述目的,即依赖的控制权由代码的内部转移到代码的外部

使用依赖注入的好处

1、松耦合、可重用性
2、提高可测试性

angular如何实现

注入器 在构造函数中声明需要用到的类

constructor(private productService: ProductService){}

提供器 在模块或组件的providers属性声明provider

providers:[ProductService]
providers:[provider:ProductService, useClass: ProductService]
providers:[provider:ProductService, useClass: AnotherProductService]

provider指定了提供器的token,跟构造器中声明的类对应。
useClass指定了具体实例化的类
providers:[provider:ProductService, useFactory: () => {...}] 工厂提供器
根据某些条件决定具体实例化哪些对象,也有可能在实例化对象时需要传入参数,这时就需要用到工厂提供器
在使用工厂方法时,如果需要依赖其他类,则需要用到第三个参数deps:[],在deps的数组中传入需要依赖的类,然后在useFactory的参数中传递进去。
providers:[provider:"APP_CONFIG", useValue: {isDev:false}]
useValue可以传值,也可以传对象

作用域规则

1、声明在模块时,对所有组件可用
2、当提供器声明在组件时,只对组件和其子组件可用
3、当声明在模块和组件具有相同的token时,组件中的提供器会覆盖模块中的提供器
4、优先将服务提供器声明在组件,只有该提供器对其他组件不可用时才声明在组件中

注入器的层级关系

应用级注入器 > 主组件注入器 > 子组件注入器

五、组件间通讯

组件的输入输出属性

输入属性:用@Input()装饰器注解的属性,属性绑定是单项的
输出属性: 用@Output()装饰器注解的属性 ,需要用到EventEmitter。从angular/core引入

声明: lastPrice: EventEmitter = new EventEmitter();
可以通过emit(value)方法把值发射出去,父组件就可以通过子组件的事件绑定接收到数据。

使用中间人模式传递数据

中间人模式:如果组件A和组件B要进行通信,他们有共同的父组件,则可以把父组件当中间人,A组件把值发射给父组件,父组件接收后把值通过B组件的Input属性传递给B组件。

如果两个组件没有共同的父组件,则可以通过服务来订阅事件。

组件生命周期及angular的变化发现机制

左边的是组件初始化调用的事件,红色的事件只调用一次,绿色的事件会被多次调用。如果组件有输入属性,则组件在被初始化时会调用ngOnChanges事件。由于这个事件是在构造器之后调用,所以不能在构造函数做初始赋值操作,最好是在ngOnInit方法中做初始化操作。


angular学习笔记_第2张图片
组件生命周期
ngOnChanges什么情况下会被调用

1、必须是输入属性发生改变
2、输入属性的地址发生改变,如果输入属性是引用类型,改变该变量的属性值是不会触发ngOnChanges事件

变更检测和DoCheck钩子

变更检测是通过zone.js来实现的


angular学习笔记_第3张图片
变更检测

事件会触发变更检测机制,变更检测机制被触发就会调用DoCheck钩子。
如果钩子上有check的钩子,当触发变更检测机制,所有带check的钩子都会被调用,所以在使用带check的钩子要非常小心。

@ViewChild装饰器

可以让父组件获取子组件的引用,调用子组件的方法。

ngAfterViewInit和ngAfterViewChecked

这两个方法都是在组件的视图被组装完毕才调用
如果组件有子组件,只有当所有子组件的视图都被组装完成后,父组件才会被调用
不要在这两个方法中去改变视图中绑定的东西,如果想改变,要写在定时器里面,不然会抛出异常。

ng-content标签可以把父组件模板中任意的片段投影到子组件中去。

ngAfterContentInit和ngAfterContentChecked

在被投影进来的内容组装完被调用

ngOnDestroy

在切换路由的时候调用
在这个钩子反订阅一个流或者清除定时器

六、表单处理

模板式表单

表单的数据模型通过组件模板中的相关指令来定义的,会受限于HTML的语法,所以,模板式表单只适合用于一些简单的场景。

NgForm -> FormGroup

angular会自动为form表单添加ngForm指令,如果不想让它接管,可以在form表单添加ngNoForm指令
ngForm可以在form之外使用,比如在div中添加
ngForm可以被模板本地变量引用

NgModule -> FormControl
NgModuleGroup -> FormGroup

响应式表单

在组件的控制器中创建一个底层的数据模型,然后使用一些特定的指令,将模板上的HTML元素与数据模型连接起来。

FormControl

FormGroup

FormArray
可以增长的自动集合

五个指令

formControl
formControlName
formGroup
formGroupName
formArrayName
指令中后面有name的不能使用属性绑定语法,也就是不能加[]
当formControl和formGroup在一个嵌套里面,则需要加name

FormBuilder便捷创建数据模型

表单验证

angular的校验器

内置校验器:Validator
常用的有required, minlength

自定义校验器

校验器名(control:FormControl): any{ return null; }

异步校验器 返回的是一个可观测的流

校验响应式表单

判断模板式表单是否有错误,可以用hasError方法。第一个参数是校验器名,第二个参数是校验的属性。如果是嵌套的属性,则传递一个数组,第一个值是一级属性,第二个值是二级属性。

getError方法可以获取到具体的报错信息

校验模板式表单

需要把自定义的校验方法封装为指令,才能在模板中调用

表单状态字段

touched和untouched 判断字段是否获取过焦点,用来控制错误信息是否显示

pristine和dirty 判断字段的值是否修改过

pending

你可能感兴趣的:(angular学习笔记)