本篇文章给大家分享Angular的一些知识点,介绍一下Angular的两表单(模板驱动表单和响应式表单)、三管道(内置管道、链式管道、自定义管道)、三绑定、三指令、五通信、八周期,希望对大家有所帮助!

1 Angular的两大表单
1.1 模板驱动表单
? 模板驱动表单:引入FormsModule
模块,表单的控制逻辑都是写在模板里的,每一个表单元素都是和一个负责管理内部表单模型的指令关联起来的。【相关教程推荐:《angular教程》】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
@Component({
selector: 'app-module-form',
template:`
<form #moduleForm= "ngForm" (submit)= "OnSubmit(moduleForm)" >
<label>用户名:
<input type= "text" name= "username" ngModel required minlength= "2" maxlength= "6" #username= "ngModel" ><br>
<ng-container *ngIf= "username.touched&&username.errors" >
<div *ngIf= "username.errors.required" >请输入用户名</div>
<div *ngIf= "username.errors.minlength" >最少2个字符</div>
<div *ngIf= "username.errors.maxlength" >最多6个字符</div>
</ng-container>
</label>
<label>
密 码:
<input style= "margin-top: 10px;" type= "text" name= "password" ngModel required minlength= "6" pattern= "[a-zA-Z0-9]+" #password= "ngModel" ><br>
<ng-container *ngIf= "password.touched&&password.errors" >
<div *ngIf= "password.errors.required" >请输入密码</div>
<div *ngIf= "password.errors.minlength" >最少6个字符</div>
<div *ngIf= "password.errors.pattern" >至少包含大小写、数字</div>
</ng-container>
</label>
<button style= "margin-top: 20px;" type= "submit" [disabled]= "!moduleForm.valid" >提交</button>
</form>
`,
styleUrls: ['./module-form.component.less']
})
export class ModuleFormComponent implements OnInit {
constructor() { }
ngOnInit() {
}
OnSubmit(moduleForm:NgForm){
console.log(moduleForm.value);
}
}
|
ログイン後にコピー
1.2 响应式表单
? 响应式表单:需要引入ReactiveFormsModule
模块,在响应式表单中,视图中的每个表单元素都直接链接到一个表单模型。
- FormControl:是构成表单的基本单位。实例用于追踪
单个表单
控件的值和验证状态 - FormGroup:用于追踪一个
表单控件组
的值和状态。 - FormGroup和FormArray的区别:formgroup既可以代表表单一部分也可以代表整个表单;formarray有一个额外的长度属性,它的formControl是没有相关的key的,只能通过访问formarray中的元素。
1 2 | <input [formControl]= "username" >
<!--不带表单的input-->
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | export class ReactiveRegistComponent implements OnInit {
formModel:FormGroup;
constructor() {
this.formModel= new FormGroup({
username: new FormControl(),
mobile: new FormControl(),
passwordsGroup: new FormGroup({
password: new FormControl(),
pconfirm: new FormControl(),
})
});
}
}
constructor(fb:FormBuilder) {
this.formModel=fb.group({
username:[''],
mobile:[''],
passwordsGroup: fb.group({
password:[''],
pconfirm:[''],
})
});
}
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, NgForm, Validators } from '@angular/forms';
@Component({
selector: 'app-module-form',
template:`
<form [formGroup]= "form" >
<label>用户名:
<input type= "text" formControlName= "username" ><br>
<ng-container *ngIf= "form.controls['username'].errors?.['required']" ><div style= "color: red;" >请输入用户名</div></ng-container>
<ng-container *ngIf= "form.controls['username'].errors?.['maxlength']" ><div style= "color: red;" >最多只能有6个字符</div></ng-container>
</label>
<label>
密 码:
<input style= "margin-top: 10px;" formControlName= "password" ><br>
<ng-container *ngIf= "form.controls['password'].errors?.['required']" ><div style= "color: red;" >请输入密码</div></ng-container>
</label>
</form>
`,
styleUrls: ['./module-form.component.less']
})
export class ModuleFormComponent implements OnInit {
form!: FormGroup;
constructor( private fb: FormBuilder) { }
ngOnInit() {
this.form = this.fb.group({
username:[null,[Validators.required,Validators.maxLength(6)]],
password:[null,[Validators.required]],
})
}
}
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 | export function whiteSpaceValidator(): ValidatorFn {
return (control: FormControl): { [s: string]: boolean } => {
const reg = new RegExp(/\s/g);
if (reg.test(control.value)) {
return { required: true };
}
};
}
|
ログイン後にコピー
2 Angular管道
2.1 内置管道
? Angular的一些内置管道:如date、uppercase、lowercase、currency、percent等,不用引入,直接在任何组件中使用。注意:用date转化的数据不能为字符串,必须为Date类数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!-- curDate = new Date (); -->
<!-- 当前时间日期为Apr 20, 2022 -->
<p>当前时间日期为{{curDate| date }}</p>
<!-- 管道参数化:当前时间日期为2022/04/20 -->
<p>当前时间日期为{{curDate| date : "yyyy/MM/dd" }}</p>
<!-- title = "Hello World!" ; -->
<!-- 转大写HELLO WORLD! -->
<p>转大写{{title|uppercase}}</p>
<!-- 转小写hello world! -->
<p>转小写{{title|lowercase}}</p>
<!-- 转换金额字符串 $0 .26 -->
<p>转换金额字符串{{0.259|currency}}</p>
<!-- 转换金额百分比26% -->
<p>转换金额百分比{{0.259|percent}}</p>
|
ログイン後にコピー
2.2 链式管道
? 链式管道:管道以多个条件指定格式输出。
1 2 | <!-- 当前时间日期为wednesday, april 20, 2022 -->
<p>当前时间日期为{{curDate| date :'fullDate'|lowercase}}</p>
|
ログイン後にコピー
2.3 自定义管道
? 自定义管道:在app.module文件的declarations中进行声明就可以在任何一个组件中使用了。
1 2 | <!-- 600000毫秒真实时间:00天00时10分00秒 -->
<p>600000毫秒真实时间:{{600000|TimeFormater}}</p>
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import { PipeTransform, Pipe } from '@angular/core';
@Pipe({
name: 'TimeFormater',
})
export class TimeFormaterPipe implements PipeTransform {
transform(value) {
if (!value || value <= 0) {
return '00天00时00分00秒';
}
const time = Math. abs (value);
const transecond = Math. round (time / 1000);
const day = Math. floor (transecond / 3600 / 24);
const hour = Math. floor ((transecond / 3600) % 24);
const minute = Math. floor ((transecond / 60) % 60);
const second = transecond % 60;
return `${this.formatTime(day)}天${this.formatTime(hour)}时${this.formatTime(minute)}分${this.formatTime(second)}秒`;
}
formatTime(t) {
return t < 10 ? '0' + t : '' + t;
}
}
|
ログイン後にコピー
3 Angular的三大绑定
3.1属性绑定
? 属性绑定的属性指的是元素、组件、指令的属性。属性的绑定是单向绑定,从组件的属性流动到目标元素的属性。
1 2 | <!--属性绑定图片路径,动态获取-->
<img src= "/static/imghw/default1.png" data-src= "https://img.php.cn/upload/image/713/396/908/1652152048222730.png" class = "lazy" [src]= "imgUrl" alt= "Angular の知識の共有: フォーム、パイプライン、バインディング、命令、通信、サイクルについて話します。" >
|
ログイン後にコピー
3.2 attribute、class和style绑定
?attribute绑定:并非所有属性都有可供属性绑定。是HTML标签上的特性,它的值只能够是字符串。通过attr.特性名
绑定。而比如标签中的id、src等这些属于Property(属性,DOM中的属性,是JavaScript里的对象)
,这些可以直接绑定就可。而attribute绑定如下:
1 2 3 4 | <table [border]= "1" >
<tr><td id= "attr" [attr.colspan]= "1+1" >One-Two</td></tr>
<tr><td>Five</td><td>Six</td></tr>
</table>
|
ログイン後にコピー
?class的绑定:静态绑定、单一属性动态绑定方式、多属性动态绑定方式、ngCLass指令绑定。
1 2 3 4 5 6 7 8 9 10 11 | .test1{
width: 100px;
height: 100px;
border: 1px solid;
}
.test2{
width: 100px;
height: 100px;
background-color: yellowgreen;
}
|
ログイン後にコピー
(1)静态绑定:可以是一个,也可以是多个,多个的class就会融合起来。
1 2 3 | <div class = "test1" ></div>
<div class = "test1 test2" ></div>
<!--多个样式会重叠-->
|
ログイン後にコピー
1 2 | <div [ class ]= "'test1'" ></div>
<div [ class ]= "'test1 test2'" ></div>
|
ログイン後にコピー
(2)单一属性动态绑定方式:取在css文件中定义好的样式进行绑定,class.样式的class名
。
1 2 | <div [ class .test1]= "true" ></div>
<div [ class .test2]= "true" ></div>
|
ログイン後にコピー
(3)多属性动态绑定方式:class的绑定
1 2 | <div [ class ]= "moreClass" ></div>
<div [ngClass]= "moreClass" ></div>
|
ログイン後にコピー
1 2 3 4 | moreClass:object = {
'test1':true,
'test2':true
}
|
ログイン後にコピー
?style的绑定:单一样式绑定、带单位的单一样式绑定、多个样式绑定。
(1)单一样式的绑定
1 | <div [style.width]= "'200px'" ></div>
|
ログイン後にコピー
(2)带单位的单一样式绑定
1 | <div [style.width.px]= "'200'" ></div>
|
ログイン後にコピー
(3)多个样式绑定
1 | `<div [style]= "moreStyle" >绑定多个形式的style</p>`
|
ログイン後にコピー
1 | moreStyle:string = 'width: 100px;height: 200px';
|
ログイン後にコピー
3.3 事件绑定
?事件绑定:带()
的特性就是事件绑定。括号内代表的是目标事件。而下面例子的事件绑定就是点击事件的绑定。
1 | <button (click)= "save()" ></button>
|
ログイン後にコピー
(1)目标事件是原生DOM元素事件,input是DOM元素input的原生事件。
1 2 3 4 5 6 7 8 9 10 11 | <input [value]= "currentUser.name" (input)= "getValue($event)" >
currentUser={
'name':''
}
getValue(ev:any){
this.currentUser.name = ev.target.value;
console.log(this.currentUser.name);
}
|
ログイン後にコピー
(2)目标事件是指令:比如ngClick、ngDblclick等。
(3)目标事件是自定义事件。目标事件 (子组件的EventEmitter实例变量)="父组件的方法(子组件数据)" 下文的父子组件通信已经有详解?。
4 Angular的三大指令
4.1 属性型指令
? 属性型指令:该指令可改变元素、组件或其他指令的外观和行为。比如:
- ngClass指令:可以通过动态地添加或移除css类来控制css来如何显示。
- ngStyle指令:可以同时设置多个内联样式。
- ngModel指令:可以双向绑定到HTML表单中的元素。
- 创建属性型指令:在app.module文件中的declarations数组中进行声明就可以在任何组件的标签元素中调用,如下:
1 | <p appHighlight>看一下指令</p>
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 | import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el:ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor( private el:ElementRef) {
}
@HostListener('mouseenter') onMouseEnter(){
this.hightlight('yellow');
}
@HostListener('mouseleave') onMouseLeave(){
this.hightlight('');
}
private hightlight(color:string){
this.el.nativeElement.style.backgroundColor = color;
}
}
|
ログイン後にコピー
4.2 结构型指令
? 结构型指令:该指令通过添加或移除DOM元素来改变DOM布局。每一个宿主元素都只能有一个结构型指令。比如ngif和ngfor不能在同一元素出现。如ngif、ngfor、ngSwitch(本身是属性型指令,它控制了两个结构型指令ngSwitchCase和ngSwitchDefault),结构型指令一般都是带***符号
的**。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appTagdisplay]'
})
export class TagdisplayDirective {
private hasView = false;
constructor( private templateRef:TemplateRef<any>, private viewContainer:ViewContainerRef) { }
@Input() set appTagdisplay(condition:boolean){
if (!condition&&!this.hasView){
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition&&this.hasView){
this.viewContainer.clear();
this.hasView = false;
}
}
}
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 | <div>
<h1>自定义结构指令</h1>
<p *appTagdisplay= "false" >
该段显示,因为appTagdisplay为false
</p>
<p *appTagdisplay= "true" >
该段不显示,因为appTagdisplay为true
</p>
</div>
|
ログイン後にコピー
4.3 组件
? 组件:也是一种指令,该指令拥有模板。
5 Angular的五大组件通信
5.1 Input与Output实现父子组件通信
通过下面的例子我们会发现Input和Output的操作都在子组件中
。父传子:在父组件中动态绑定属性,在子组件中Input获取父组件传来的属性。子传父:子组件创建一个实例化EventEmitter对象,EventEmitter 的核心就是事件触发与事件监听器功能的封装;父组件:通过事件绑定调用带参自定义函数接受子组件传来的数据(自定义函数的参数)。
? 父组件:双向绑定fatherData也就是当前输入框输入的信息,点击发送事件触发传给子组件的currentData添加数据并清空当前输入框的信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <div class = "chan" >
<div class = "father" >
<ng-container *ngIf= "!isClear" >
<div *ngFor= "let item of currentData" >
<span>{{item}}</span>
</div>
</ng-container>
<div class = "footer" >
<input style= "width:178px" [(ngModel)]= "fatherData" />
<button (click)= "send()" >发送</button>
<button (click)= "isClear=true" >清空记录</button>
</div>
</div>
<app-son [dataSource]= "currentData" (sonSend)= "getSonInfo($event)" ></app-son>
</div>
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import { Component, OnInit } from '@angular/core';
export class FatherComponent implements OnInit {
isClear:boolean=false;
fatherData:any;
currentData:Array<any>=[];
constructor() { }
ngOnInit() {
this.fatherData = this.currentData;
}
send(){
this.currentData.push( "我是父组件的数据:" +this.fatherData);
this.fatherData='';
}
getSonInfo(event:any){
this.currentData.push( "我是子组件的数据:" +event);
}
}
|
ログイン後にコピー
? 子组件:输入框输入sonData,点击发送事件触发子组件事件发射数据,然后父组件就可以通过子组件绑定的事件发射从父组件通过事件方法获取当前子组件发送的数据。
1 2 3 4 5 6 7 8 9 10 11 12 | <div class = "son" >
<ng-container *ngIf= "!isClear" >
<div *ngFor= "let item of currentData" >
<span>{{item}}</span>
</div>
</ng-container>
<div class = "footer" >
<input style= "width:178px" [(ngModel)]= "sonData" />
<button (click)= "send()" >发送</button>
<button (click)= "isClear=true" >清空记录</button>
</div>
</div>
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import { OnInit } from '@angular/core';
export class SonComponent implements OnInit{
@Input() dataSource:any=0;
@Output() sonSend = new EventEmitter<any>();
isClear:boolean=false;
sonData:any;
currentData:Array<any>=[];
constructor() { }
ngOnInit(): void {
this.currentData = this.dataSource;
}
send(){
this.sonSend.emit(this.sonData);
this.sonData='';
}
}
|
ログイン後にコピー

5.2 通过本地变量实现父子组件的通信
在父组件的模板中创建一个代表子组件的本地变量,通过调用这个变量就可以调用子组件中的属性和方法。
1 2 3 | <div>我是父组件</div>
<div>子组件:{{sonTpl.myName}}</div>
<app-son #sonTpl></app-son>
|
ログイン後にコピー
5.3 通过@ViewChild实现父子组件的通信
父组件的js中定义@ViewChild(SonComponent) childTpl: any;
,注意在html必须要调用子组件元素,不然会直接报错,且不能直接调用childTpl.myName获取子组件中的变量。
1 2 3 | <div>我是父组件</div>
<button (click)= "childTpl.getName()" >子组件按钮</button>
<app-son></app-son>
|
ログイン後にコピー
1 2 3 4 | getName(){
console.log('我是子组件的getName方法');
}
|
ログイン後にコピー
5.4 通过共享服务Service实现非父子组件通信
栗子来自书籍《Angular企业级应用开发实战》
-p143:

? Service服务:主要控制准备开始、和确认按钮的动作进行消息的传递。注意这个服务的定义一定是共享的,不要在各个组件下独自注入providers
中,因为单独引入service只是在当前组件有效,每个组件调用一次都是独立的,互不影响,这就不是组件通信需要的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MissionService {
private missionAnnounceSource = new Subject<string>();
private misssionConfirmedSource = new Subject<string>();
missionAnnounce$ = this.missionAnnounceSource.asObservable();
missionConfirm$ = this.misssionConfirmedSource.asObservable();
constructor() {}
announceMission(mission:string){
this.missionAnnounceSource.next(mission);
}
confirmMission(astronaut:string){
this.misssionConfirmedSource.next(astronaut);
}
}
|
ログイン後にコピー
? MissioncontrolComponent:这是一个主要界面的组件,在界面中调用了astronaut组件。当前组件就是父组件,而astronaut组件就是一个子组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import { Component, OnInit } from '@angular/core';
import { MissionService } from 'src/app/service/mission.service';
@Component({
selector: 'app-missioncontrol',
template: `<h2>导弹控制器</h2>
<button (click)= "announce()" >准备开始</button>
<app-astronaut *ngFor= "let item of astronauts" [astronaut]= "item" >
</app-astronaut>
<h3>日志</h3>
<ul>
<li *ngFor= "let event of history" >{{event}}</li>
</ul>
`,
})
export class MissioncontrolComponent implements OnInit {
astronauts = ['操作员1','操作员2','操作员3'];
history:string[] = [];
missions = ['发射导弹'];
nextMession = 0;
constructor( private misssionSvc:MissionService) {
misssionSvc.missionConfirm$.subscribe((astronaut)=>{
this.history.push(`${astronaut}已经确认`);
})
}
announce(){
let mission = this.missions[this.nextMession++];
this.misssionSvc.announceMission(mission);
this.history.push(`任务 "${mission}" 进入准备`);
if (this.nextMession>=this.missions.length){
this.nextMession = 0;
}
}
ngOnInit(): void {
}
}
|
ログイン後にコピー
? AstronautComponent:点击确认,向父组件传递确认的操作员信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { MissionService } from 'src/app/service/mission.service';
@Component({
selector: 'app-astronaut',
template: `
<p>
{{astronaut}}:<strong>{{mission}}</strong><button (click)= "confirm()" [disabled]= "!announced||confirmed" >确认</button>
</p>
`,
})
export class AstronautComponent implements OnInit,OnDestroy{
@Input() astronaut:string='';
mission = '<没有任务>';
confirmed = false;
announced = false;
subscription:Subscription;
constructor( private missionSvc:MissionService) {
this.subscription = missionSvc.missionAnnounce$.subscribe((mission)=>{
this.mission = mission;
this.announced = true;
this.confirmed = false;
})
}
confirm(){
this.confirmed = true;
this.missionSvc.confirmMission(this.astronaut);
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
ngOnInit() {
}
}
|
ログイン後にコピー
5.5 路由传值
? 按钮点击跳转:路由传参数由分号隔开。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-father',
template:`<button (click)= "linkSon()" >按钮跳到儿子组件中</button>`
})
export class FatherComponent implements OnInit {
obj:any=[
'书悟空',
'唐僧',
];
constructor( private router:Router) {}
ngOnInit() {}
linkSon(){
this.router.navigate(['/son',{ name:this.obj,id:10010}]);
}
}
|
ログイン後にコピー
1 2 3 4 | this.route.params.subscribe((route)=>{
console.log(route);
})
|
ログイン後にコピー
ログイン後にコピー
? 链接点击跳转:路由传参通过queryParams属性控制,由?、&符号分隔开。
1 2 | <a [routerLink]= "['/son']" [queryParams]= "{id:10010,name:this.obj}" >链接跳到儿子组件中</a>
|
ログイン後にコピー
1 2 3 4 | this.route.queryParams.subscribe((route)=>{
console.log(route);
})
|
ログイン後にコピー
? 链接点击跳转:直接是用/分割路由传参。
1 | { path: 'son/:id', component: SonComponent },
|
ログイン後にコピー
1 2 | <a [routerLink]= "['/son',10010]" >链接跳到儿子组件中</a>
|
ログイン後にコピー
1 2 3 4 | this.route.params.subscribe((route)=>{
console.log(route);
})
|
ログイン後にコピー
ログイン後にコピー
还有其他通信方式:浏览器本地传值(localStorge、SessionStorge)、cookie
6 Angular的八大生命周期
6.1 ngOnChanges()
当angular检测到组件(或指令)
重新设置数据绑定输入属性时响应。在被绑定的输入属性的值发生变化时调用,首次调用一定会发生在
ngOnInit()之前
,每一次改变绑定数据就调用一次这个钩子。OnChanges() 对应的函数 ngOnChanges(),该函数获取了一个对象,对象把每个发生变化的属性名映射在SimpleChange对象中,对象有属性当前值currentValue
和前一个值previousValue
。
? 父组件:
1 2 3 4 5 6 7 8 | <!--父组件html-->
<div>
<span>我是父组件:</span>
<input [(ngModel)]= "dataSource" />
<span style= "margin-left: 20px;" >{{dataSource}}</span>
</div>
<div style= "height: 20px;" ></div>
<app-two [data]= "dataSource" ></app-two>
|
ログイン後にコピー
? 子组件:
1 2 3 4 5 6 7 | <!--子组件TwoComponent html-->
<div>
<span>我是子组件:</span>
<button (click)= "increment()" >+</button>
<span style= "margin: 0 20px;" >{{data}}</span>
<button (click)= "decrement()" >-</button>
</div>
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import { Component, Input, OnInit, SimpleChanges, OnChanges } from '@angular/core';
export class TwoComponent implements OnInit,OnChanges {
@Input() data:any=0;
constructor() { }
ngOnInit(): void {
console.log('ngOnInit',this.data);
}
increment(){
this.data++;
}
decrement(){
this.data--;
}
ngOnChanges(changes: SimpleChanges): void {
console.log( "previousValue:" ,changes['data'].previousValue);
console.log( "currentValue:" ,changes['data'].currentValue);
}
}
|
ログイン後にコピー
注意地,在子组件中操作是不能触发Onchanges钩子函数地,它是控制组件上属性的改变而触发。


6.2 ngOnInit()
在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件,在第一轮ngOnChanges()完成之后调用,只调用一次
。
6.3 ngDoCheck()
检测变化,在每一个Angular变更检测周期(变化监测)中调用,在执行ngOnChanges
和ngOnInit()
方法之后调用。不管是数据绑定还是鼠标的点击事件,只要触发了都会触发这个钩子的调用。
1 2 3 4 | <div>
<input [(ngModel)]= "dataSource" />
<span style= "margin-left: 20px;" >{{dataSource}}</span>
</div>
|
ログイン後にコピー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import { DoCheck,OnInit } from '@angular/core';
export class SonComponent implements OnInit,DoCheck {
dataSource:any;
constructor() { }
ngOnInit(): void {
console.log( "ngOnInit!" );
}
ngDoCheck(): void {
console.log( "DoCheck:" ,this.dataSource);
}
}
|
ログイン後にコピー

6.4 ngAfterContentInit()
把内容投影进组件之后调用,在第一次执行ngDoCheck方法之后调用,只调用一次
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import { AfterContentChecked, AfterContentInit,DoCheck, Input, OnInit } from '@angular/core';
export class SonComponent implements OnInit,DoCheck,AfterContentInit{
@Input() data:any=0;
dataSource:any;
constructor() { }
ngOnInit(): void {
console.log( "ngOnInit!" );
}
ngAfterContentInit(): void {
console.log( "ngAfterContentInit!" ,this.dataSource);
}
ngDoCheck(): void {
console.log( "DoCheck:" ,this.dataSource);
}
}
|
ログイン後にコピー

6.5 ngAfterContentChecked()
在每次完成被投影组件内容的变更检测之后调用。在执行ngAfterContentInit()
和ngDoCheck()
方法之后调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import { AfterContentChecked, AfterContentInit, DoCheck, Input, OnInit } from '@angular/core';
export class SonComponent implements OnInit,DoCheck,AfterContentInit,AfterContentChecked{
@Input() data:any=0;
dataSource:any;
constructor() { }
ngOnInit(): void {
console.log( "ngOnInit!" );
}
ngAfterContentInit(): void {
console.log( "ngAfterContentInit!" ,this.dataSource);
}
ngAfterContentChecked(): void {
console.log( "ngAfterContentChecked!" ,this.dataSource);
}
ngDoCheck(): void {
console.log( "DoCheck:" ,this.dataSource);
}
}
|
ログイン後にコピー

6.6 ngAfterViewInit()
在初始化完组件视图及其子视图之后调用,在第一次执行ngAfterContentChecked()方法之后调用,只调用一次
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | export class SonComponent implements OnInit,DoCheck,AfterContentInit,AfterContentChecked,AfterViewInit{
dataSource:any;
constructor() { }
ngOnInit(): void {
console.log( "ngOnInit!" );
}
ngAfterContentInit(): void {
console.log( "ngAfterContentInit!" ,this.dataSource);
}
ngAfterContentChecked(): void {
console.log( "ngAfterContentChecked!" ,this.dataSource);
}
ngAfterViewInit(): void {
console.log( "ngAfterViewInit!" );
}
ngDoCheck(): void {
console.log( "DoCheck:" ,this.dataSource);
}
}
|
ログイン後にコピー

6.7 ngAfterViewChecked()
在每次完成组件视图和子视图的变更检测之后调用。在执行ngAfterViewInit()
和ngAfterContentChecked()
方法之后调用。

6.8 ngOnDestroy()
在Angular每次销毁指令/组件之前调用并清扫,在这里反订阅可观察对象和分离事件处理器,以防内存泄漏。什么时候会调用这个生命周期呢?也就是平时我们切换组件或从一个组件跳转到另一个组件
的时候,这时候就会触发组件的销毁。
更多编程相关知识,请访问:编程视频!!
以上がAngular の知識の共有: フォーム、パイプライン、バインディング、命令、通信、サイクルについて話します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。