(不适合没有一点框架基础直接看总结)
(自己因为实习快速过了一遍基础,顺手做的笔记,可能写的不够详细)
插值:{{}}
属性绑定:[xxx]
条件判断:*ngIf
循环语句:*ngFor=“let color of clolors let i=index let odd=odd”
分支语句:[ngSwitch],*ngSwitchCase,*ngSwitchDefault
事件绑定:(事件) = “函数(可传参)”
模板引用变量(类似于ref):#模板变量(之后可以在组件模板中的任何地方引用某个模板变量)
如果是想要获取组件实例,从而获取子组件数据,或调用子组件方法
<app-hello #myChild>
@ViewChild(‘myChild’) child: any; 之后父组件中可用child得到该子组件实例
双向绑定:[(ngModel)]=“变量名”(使用之前需要导入FormsModule板块)
表单控件:
① 注册响应式表单模块,即在app组件导入ReactiveFormsModule,之后子组件就可以直接使用
② 在使用的组件中导入FormControl
③ 生成一个新的FormControl实例
xxx:FormControl = new FormControl(‘’)
④ 在模块中在对应的表单元素上写,例
[formControl]=‘age’
⑤ 通过age.value可获取表单元素的值,通过age.setValue(xxx)修改值
表单控件分组:
① 在使用的组件导入FormGroup
② 生成一个FormGroup实例
loginForm = new FormGroup({
userNmae: new FormControl(‘’),
password: new FormControl(‘’),
});
③ 在form元素上写[formGroup]=‘loginForm’,在表单的其他元素写
formControlName='userName’和formControlName=‘password’
④ 通过loginForm.value可获取数据组成的对象
表单验证:
需通过绑定ngModel的引用来拿到当前组件的信息
#xxx=‘ngModel’
(例,表单元素添加required表示必填,可通过xxx.valid判断验证是否通过)
且使用了三个css类来更新控件,以便反映当前状态
状态 为true时的类 为false时的类
控件已经被访问过 ng-touched ng-untouched
控件值已经变化 ng-dirty ng-pristine
控件值是有效的 ng-valid ng-invalid
自定义表单验证:
① 需要引入FormGroup,FormBuilder,Validators(里面有些内置的验证)
② 在construtor中注入FormBuilder
constructor(private fb:FormBuilder) {}
③ 例,将自定义判断加进去
valiDataForm = this.fb.group({
userName: [‘’, [Validators.required, Validators.maxLength(18)]],
password: [‘’, [this.passWordVal]],
phone: [‘’, [Validators.required, this.phoneVal]]
})
例phoneVal,会接收到phone(FormControl对象),返回一个对象
④ 如果验证不通过,可以通过valiDataForm.get(‘phone’).errors身上找到原因(自定义验证,可以找到当时返回的对象)
管道:{{ 输入数据 | 管道 : 管道参数 }} 可多个管道连用
如果要自定义管道,则ng g p xxx
常用管道:date,json,uppercase,lowercase等等
生命周期(按顺序):
① ngOnChanges()
② ngOnInit()(只调用一次)
③ ngDoCheck()
④ ngAfterContentInit()(只调用一次)
⑤ ngAfterContentChecked()
⑥ ngAfterViewInit()(只调用一次)
⑦ ngAfterViewChecked()
⑧ ngOnDestroy()
生命周期详解:
- 构造函数(这个不是生命周期里的)
首先运行的是构造函数,Angular中的组件就是基于class类实现的,在Angular中,constructor用于注入依赖,组件的构造函数会在所有的生命周期钩子之前被调用
主要作用:
a:依赖注入
b:执行简单的数据初始化操作 - ngOnInit
在第一次ngOnChanges执行之后调用,并且只被调用一次。它主要用于执行组件的其它初始化操作或获取组件输入的属性值。
在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件(即此时可以访问到父组件给组件传的值和绑定的事件等,而构造函数里,只能访问到自己组件里的属性方法(就类似普通对象里的构造函数))
使用ngOnInit()有两个原因:
a:在构造函数之后马上执行复杂的初始化逻辑
b:在Angular设置完输入属性之后,对该组件进行准备 - ngOnChanges
当输入属性被改变时(父子组件传值或父组件改数据)才会调用的值发生变化的时候,Angular将会主动调用ngOnChanges方法。它会获得一个SimpleChanges对象,包含绑定属性的新值和旧值,它主要用于监测组件输入属性的变化。当Angular(重新)设置数据绑定输入属性时响应。 该方法接受当前和上一属性值的SimpleChanges对象(即当被绑定的输入属性的值发生变化时调用,且首次调用一定会发生在ngOnInit()之前)
(如果是想监听本组件内的属性变化,可以通过getter和setter直接监听即可) - ngOnDestory
在Angular销毁指令/组件之前,将会调用 ngOnDestory 方法。它主要用于执行一些清理操作,比如:移除事件监听、清除定时器、退订Observable 等,这是在该组件消失之前,可用来通知应用程序中其它部分的最后一个时间点,用来释放那些不会被垃圾收集器自动回收的各类资源的地方,如果不这么做,就会有导致内存泄露的风险 - ngDoCheck
并不止当输入属性被改变时(父子组件传值或父组件改数据),而是可以检测一切数据的变化,这个变化不一定修改了数据,鼠标移动等操作也会执行ngDoCheck(),只有很少的调用是由于数据修改而触发,所以尽量少用 ngDoCheck(),容易造成性能问题,如果只是想监听组件输入属性的变化用ngOnChanges() - ngAfterContentInit
在组件使用ng-content指令的情况下,Angular 会在将外部内容放到视图后用。它主要用于获取通过 @ContentChild 或 @ContentChildren 属性装饰器查询的内容视图元素。当把内容投影进组件之后调用。第一次ngDoCheck()之后调用,只调用一次 - ngAfterContentChecked
在组件使用 ng-content 指令的情况下,Angular 会在检测到外部内容的绑定或者每次变化的时候调用。每次完成被投影组件内容的变更检测之后调用。ngAfterContentInit()和每次ngDoCheck()之后调用 - ngAfterViewInit
在组件相应的视图初始化之后调用,它主要用于获取通过 @ViewChild 或 @ViewChildren 属性装饰器查询的视图元素。
初始化完组件视图及其子视图之后调用。第一次ngAfterContentChecked()之后调用,只调用一次 - ngAfterViewChecked
组件每次检查视图时调用,每次做完组件视图和子视图的变更检测之后调用。ngAfterViewInit()和每次ngAfterContentChecked()之后调用
投影(类似于vue中的插槽):
在父组件中:<childrenCompoent><div>…</div></childrenCompoent>
在子组件中:<ng-content></ng-content>
若组件模板含有多个ng-content标签:
~ 为了区分投影的内容可以投影到对应ng-content标签,需要使用ng-content标签上的select属性作为识别。
~ select属性支持标签名、属性、CSS 类和 :not 伪类的任意组合。
~ 不添加属性的标签将作为默认插槽。所有为匹配的投影内容都会投影在该ng-content的位置。
在父组件中:<childrenCompoent><div test>…</div><div></div></childrenCompoent>
在子组件中:<ng-content select=”[test]”></ng-content>
ContentChild和ViewChild:
ContentChild:与内容子节点有关,操作投影进来的内容,在父组件的ngAfterContentInit生命周期钩子中才能成功获取通过ContentChild查询的元素(用来从通过Content Projection方式 (ng-content) 设置的视图中获取匹配的元素)
ViewChild:与视图子节点有关,操作自身的视图内容,在父组件的ngAfterViewInit生命周期钩子中才能成功获取通过ViewChild查询的元素(用来从模板视图中获取匹配的元素)
(都有对应的复数形式装饰器ContentChildren和ViewChildren)
ng-container标签:
ng-container既不是一个Component,也不是一个Directive,只是单纯的一个特殊tag。ng-container可以直接包裹任何元素,包括文本,但本身不会生成元素标签,也不会影响页面样式和布局。包裹的内容,如果不通过其他指令控制,会直接渲染到页面中,例ngFor和ngIf不能同时处在一个元素上,所以如果要在不添加额外的html标签的情况下达到同样的效果就可以用ng-container
属性传递:
父组件:<app-title [title]=’title’></app-title>
子组件:
① 先注入
@Input()
title?:string(之后可修改值)
② 之后模板中可直接使用
{{title}}
组件交互:
① Input
② Output(父组件给子组件传递事件,子组件通过@Output触发)
父组件:传递事件,即 (事件名)=”调用函数”
<app-hello (addList)=”addListFun($event)”></app-hello>
子组件:
@Output() addList = new EventEmitter()
之后通过this.addList.emit(数据参数)
服务:
把数据获取和保存的职责抽离出来,委托给某个服务,所以服务充当数据访问,逻辑处理的功能,为了让组件专注于数据展示,通过@Injectable()装饰器标识服务(ng g s xxx)
@Injectable({
providedIn: ‘root’
})
providedIn设置作用域,root即表示注入到app.module.ts,或值为null,表示不设定区域,还可以是某个模块的名字(一般就是懒加载模式)
在需要使用的组件中import引入,并注册
constructor(private xxxService:XxxService) {}
之后即可直接this.xxxService调用
由于服务可以注入给多个组件,所以也可以通过这个特性来实现多个组件用一组数据
路由:
路由配置:在app-routing.module.ts中配置路由
const routes: Routes=[
{
Path: ‘xxx’,
Component: xxx
}
]
(当path值为’’,则默认匹配,若path值为’*’,则通配符匹配)
设置路由组件渲染的位置:
<router-outlet></out-let>
跳转路径:(设置路由选中时class的值:routerLinkActive)
<a [routerLink]=”[‘/home’]” routerLinkActive=”router-link-active”>
路由嵌套:
Children: [{}, {}]
路由传参:
query传参:
<a [routerLink]=”[‘/home’]” [queryParams]=”{id:3, name: ‘abc’}”>xxx</a>
获取query参数:
import {ActivatedRoute} from ‘@angular/router’;
constructor(private routerinfo:ActivatedRoute) {}
this.routerinfo.snapshot.queryParams[‘id’]
params传参:
<a [routerLink]=”[‘/hello’, ‘2’, ‘3’] …>xxx</a>
获取params参数:
① 在路由配置的时,需有占位符path: ‘hello/:name’
② this.routerinfo.params.subscribe((params:Params) => {
this.name = params[‘name’] // params即传入的所有params参数组成的对象
})