日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Angular 个人深究(四)【生命周期钩子】

發(fā)布時(shí)間:2023/12/2 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Angular 个人深究(四)【生命周期钩子】 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Angular 個(gè)人深究(四)【生命周期鉤子】

定義:

每個(gè)組件都有一個(gè)被 Angular 管理的生命周期。

Angular 創(chuàng)建它,渲染它,創(chuàng)建并渲染它的子組件,在它被綁定的屬性發(fā)生變化時(shí)檢查它,并在它從 DOM 中被移除前銷毀它。

Angular 提供了生命周期鉤子,把這些關(guān)鍵生命時(shí)刻暴露出來,賦予你在它們發(fā)生時(shí)采取行動(dòng)的能力。

除了那些組件內(nèi)容和視圖相關(guān)的鉤子外,指令有相同生命周期鉤子。

概覽:

?ngOnChanges()?

當(dāng) Angular(重新)設(shè)置數(shù)據(jù)綁定輸入屬性時(shí)響應(yīng)。 該方法接受當(dāng)前和上一屬性值的 SimpleChanges?對象

當(dāng)被綁定的輸入屬性的值發(fā)生變化時(shí)調(diào)用,首次調(diào)用一定會(huì)發(fā)生在?ngOnInit()?之前。

?ngOnInit()?

在 Angular 第一次顯示數(shù)據(jù)綁定和設(shè)置指令/組件的輸入屬性之后,初始化指令/組件。

在第一輪?ngOnChanges()?完成之后調(diào)用,只調(diào)用一次。

?ngDoCheck()?

檢測,并在發(fā)生 Angular 無法或不愿意自己檢測的變化時(shí)作出反應(yīng)。

在每個(gè) Angular 變更檢測周期中調(diào)用,ngOnChanges()?和?ngOnInit()之后。

?ngAfterContentInit()?

當(dāng)把內(nèi)容投影進(jìn)組件之后調(diào)用。

第一次?ngDoCheck()?之后調(diào)用,只調(diào)用一次。

?ngAfterContentChecked()?

每次完成被投影組件內(nèi)容的變更檢測之后調(diào)用。

ngAfterContentInit()?和每次?ngDoCheck()?之后調(diào)用

?ngAfterViewInit()?

初始化完組件視圖及其子視圖之后調(diào)用。

第一次?ngAfterContentChecked()?之后調(diào)用,只調(diào)用一次。

?ngAfterViewChecked()?

每次做完組件視圖和子視圖的變更檢測之后調(diào)用。

ngAfterViewInit()?和每次?ngAfterContentChecked()?之后調(diào)用。

?ngOnDestroy()?

當(dāng) Angular 每次銷毀指令/組件之前調(diào)用并清掃。 在這兒反訂閱可觀察對象和分離事件處理器,以防內(nèi)存泄漏。

在 Angular 銷毀指令/組件之前調(diào)用。

范例:

  ngOnChanges()、ngInit

test2.component.ts

// test2.component.ts:

import { Component, OnInit,Input } from '@angular/core'; @Component({selector: 'app-test2',templateUrl: './test2.component.html',styleUrls: ['./test2.component.css'] })
//需要繼承 OnInit、OnChanges 接口 export class Test2Component implements OnInit OnChanges{
// 兩個(gè)input 來自 父組件 test1@Input() test2_value1: string;@Input() test2_value2: string;constructor() { }ngOnInit() {
          //判斷 ngOnInit的執(zhí)行順序console.log("這里執(zhí)行ngOnInit");}ngOnChanges(changes:SimpleChanges){console.log(changes);for (let propName in changes) {let chng = changes[propName];let cur = JSON.stringify(chng.currentValue);let prev = JSON.stringify(chng.previousValue);console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`);}} }

 test1.component.html

<!-- test1.component.html --> <p>test1 works! </p> <label> test1 value</label> <input type="text" [(ngModel)]="test1_value1" > <input type="text" [(ngModel)]="test1_value2" > <!-- 將test1_value1的值給test2_value1... --> <app-test2 [test2_value1]="test1_value1" [test2_value2]="test1_value2"></app-test2>

結(jié)果:

 

說明:

  • 剛刷新頁面時(shí),將test2_value1、test2_value2的值 從 undefined 變成 1、2。
  • 頁面更改test1_value1,將test2_value1的值? 從? 1 變成? 11。
  • 以此類推, 可以使用 ngOnChanges對值發(fā)生變化時(shí)進(jìn)行處理。
  • ngInit 的執(zhí)行順序在 ngOnChanges之后,可以做一下初始化的工作

?

  ngDoCheck()

test2.component.ts

import { Component, OnInit,Input,OnChanges,DoCheck} from '@angular/core'; @Component({selector: 'app-test2',templateUrl: './test2.component.html',styleUrls: ['./test2.component.css'] })
//需要實(shí)現(xiàn) DoCheck 接口 export class Test2Component implements OnInit OnChanges DoCheck{@Input() test2_value1: string;@Input() test2_value2: string;constructor() { }ngOnInit() {//console.log("這里執(zhí)行ngOnInit");}ngOnChanges(changes:SimpleChanges){//console.log(changes);for (let propName in changes) {let chng = changes[propName];let cur = JSON.stringify(chng.currentValue);let prev = JSON.stringify(chng.previousValue);//console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`);}}ngDoCheck(){console.log("執(zhí)行ngDoCheck");} }  

結(jié)果:

說明:

  • 刷新頁面的時(shí)候,執(zhí)行了兩次。
  • 每次鼠標(biāo)放到,input框上就會(huì)執(zhí)行一次
  • 更改input值,也會(huì)執(zhí)行一次,開銷非常大。慎用!

  ngAfterContentInit()

app.component.ts

import { Component } from '@angular/core';@Component({selector: 'app-root',//templateUrl: './app.component.html',//在app主組價(jià)中,將test2組件放到test1組件中,template: `<app-test1><app-test2></app-test2></app-test1>`,styleUrls: ['./app.component.css'] }) export class AppComponent {title = 'app'; }

test1.component.ts

import { Component, OnInit,OnChanges} from '@angular/core';@Component({selector: 'app-test1',//templateUrl: './test1.component.html',//ng-content指定的是外來的組件 在組件app中定義的 test2組件//同樣在test1組件中,也增加test2 組件 template: `<div> <ng-content></ng-content> <app-test2></app-test2> </div>`,styleUrls: ['./test1.component.css'] }) export class Test1Component implements OnInit, OnChanges{test1_value1:string;test1_value2:string;constructor() { }ngOnInit() {this.test1_value1="1"this.test1_value2="2"}ngOnChanges(){console.log("onchange");} }

test2.component.ts

import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit} from '@angular/core'; @Component({selector: 'app-test2',templateUrl: './test2.component.html',styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit{@Input() test2_value1: string;@Input() test2_value2: string;constructor() { }ngOnInit() {//console.log("這里執(zhí)行ngOnInit"); }ngOnChanges(changes:SimpleChanges){//console.log(changes);for (let propName in changes) {let chng = changes[propName];let cur = JSON.stringify(chng.currentValue);let prev = JSON.stringify(chng.previousValue);//console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); }}ngDoCheck(){console.log("執(zhí)行ngDoCheck");}ngAfterContentInit(){console.log("執(zhí)行ngAfterContentInit");} }

?

結(jié)果:

說明:

  • ngAfterContentInit會(huì)在外來內(nèi)容被投影到組件中之后 調(diào)用,也就是說當(dāng)test2組件以html的形式投影到test1組件之后執(zhí)行,
  • 因?yàn)槭褂脙煞N方式進(jìn)行投影了兩次,所以ngAfterContentInit執(zhí)行了兩次
  • 其他操作只會(huì)增加ngDoCheck的次數(shù),并沒有增加ngAfterContentInit的次數(shù)

?

  ngAfterContentCheck()

?test2.component.ts

import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit,AfterContentCheck} from '@angular/core'; @Component({selector: 'app-test2',templateUrl: './test2.component.html',styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit,AfterContentCheck{@Input() test2_value1: string;@Input() test2_value2: string;constructor() { }ngOnInit() {//console.log("這里執(zhí)行ngOnInit"); }ngOnChanges(changes:SimpleChanges){//console.log(changes);for (let propName in changes) {let chng = changes[propName];let cur = JSON.stringify(chng.currentValue);let prev = JSON.stringify(chng.previousValue);//console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); }}ngDoCheck(){console.log("執(zhí)行ngDoCheck");}ngAfterContentInit(){console.log("執(zhí)行ngAfterContentInit");}ngAfterContentChecked(){console.log("執(zhí)行ngAfterContentChecked");} }

結(jié)果:

說明:

  • 在執(zhí)行ngDoCheck之后 一定會(huì)執(zhí)行一次ngAfterContentInit
  • 每次完成被投影組件內(nèi)容的變更檢測之后調(diào)用
  • 其他代碼沒貼出來,就是跟上一個(gè)是一樣的

  ngAfterViewInit()

?test1.component.ts

import { Component, OnInit,OnChanges,ViewChild} from '@angular/core'; import {Test2Component} from "../test2/test2.component"@Component({selector: 'app-test1',//templateUrl: './test1.component.html',template: `<div> <input type="text" [(ngModel)]="test1_value1" > <input type="text" [(ngModel)]="test1_value2" ><ng-content></ng-content> <app-test2 [test2_value1]="test1_value1" [test2_value2]="test1_value2"></app-test2> </div>`,styleUrls: ['./test1.component.css'] }) export class Test1Component implements OnInit, OnChanges{test1_value1:string;test1_value2:string;constructor() { } @ViewChild(Test2Component);ngOnInit() {this.test1_value1="1"this.test1_value2="2"}ngOnChanges(){console.log("onchange");} }

test2.component.ts

import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit,AfterContentCheck, AfterViewChecked, AfterViewInit} from '@angular/core'; @Component({selector: 'app-test2',templateUrl: './test2.component.html',styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit,AfterContentCheck ,AfterViewChecked, AfterViewInit{@Input() test2_value1: string;@Input() test2_value2: string;constructor() { }ngOnInit() {//console.log("這里執(zhí)行ngOnInit"); }ngOnChanges(changes:SimpleChanges){//console.log(changes);for (let propName in changes) {let chng = changes[propName];let cur = JSON.stringify(chng.currentValue);let prev = JSON.stringify(chng.previousValue);//console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); }}ngDoCheck(){console.log("執(zhí)行ngDoCheck");}ngAfterContentInit(){console.log("執(zhí)行ngAfterContentInit");}ngAfterContentChecked(){console.log("執(zhí)行ngAfterContentChecked");}ngAfterViewInit(){console.log("執(zhí)行ngAfterViewInit");} }

結(jié)果:

說明:

  • 在每次創(chuàng)建了組件的子視圖后調(diào)用,每次在test1組件中創(chuàng)建test2組件時(shí)都會(huì)調(diào)用,
  • 在test1組件中,需要使用@ChildView 裝飾器,將test2component裝飾一下

  ngAfterViewChecked

?test2.component.ts

import { Component, OnInit,Input ,OnChanges,DoCheck,SimpleChanges,AfterContentInit,AfterContentCheck, AfterViewChecked, AfterViewInit} from '@angular/core'; @Component({selector: 'app-test2',templateUrl: './test2.component.html',styleUrls: ['./test2.component.css'] }) export class Test2Component implements OnInit,OnChanges,DoCheck,AfterContentInit,AfterContentCheck ,AfterViewChecked, AfterViewInit{@Input() test2_value1: string;@Input() test2_value2: string;constructor() { }ngOnInit() {//console.log("這里執(zhí)行ngOnInit"); }ngOnChanges(changes:SimpleChanges){//console.log(changes);for (let propName in changes) {let chng = changes[propName];let cur = JSON.stringify(chng.currentValue);let prev = JSON.stringify(chng.previousValue);//console.log(`${propName}: 新值 = ${cur}, 舊值 = ${prev}`); }}ngDoCheck(){console.log("執(zhí)行ngDoCheck");}ngAfterContentInit(){console.log("執(zhí)行ngAfterContentInit");}ngAfterContentChecked(){console.log("執(zhí)行ngAfterContentChecked");}ngAfterViewInit(){console.log("執(zhí)行ngAfterViewInit");}ngAfterViewChecked(){console.log("執(zhí)行ngAfterViewChecked");} }

結(jié)果:

說明:

  • 上圖紅色框是,頁面刷新完后執(zhí)行的ngAfterViewChecked,前兩次是伴隨init一起的,后面兩個(gè)是,test1給test2賦值導(dǎo)致的
  • 上圖綠色框是,更改test1中的一個(gè)值,導(dǎo)致了更改了test2的值執(zhí)行的ngAfterViewChecked
  • 我再test1組件的兩個(gè)input上,鼠標(biāo)焦點(diǎn)來回切換時(shí),同樣也會(huì)執(zhí)行ngAfterViewChecked,還是慎用這個(gè)鉤子函數(shù)吧

  OnDestroy

test1.component.ts

import { Component, OnInit,OnChanges,ViewChild} from '@angular/core'; import {Test2Component} from "../test2/test2.component"@Component({selector: 'app-test1',//templateUrl: './test1.component.html', template: `<div> <input type="text" [(ngModel)]="test1_value1" ><input type="text" [(ngModel)]="test1_value2" ><ng-content></ng-content><app-test2 [test2_value1]="test1_value1" [test2_value2]="test1_value2"></app-test2> <div *ngFor="let test of tests" appTest4 class="tests">{{test}}</div><input type="button"value="add" (click)="addDiv()"><input type="button"value="delete"(click)="deleteDiv()"></div>`,styleUrls: ['./test1.component.css'] }) export class Test1Component implements OnInit, OnChanges{test1_value1:string;test1_value2:string;tests:any;constructor() { }@ViewChild(Test2Component) viewChild:Test2Component;ngOnInit() {this.test1_value1="1"this.test1_value2="2"this.tests=[1,2,3]}ngOnChanges(){console.log("onchange");}addDiv(){this.tests.push("1212");}deleteDiv(){this.tests=[];} }

test4.directive.ts

import { Directive, OnInit, OnDestroy } from '@angular/core';@Directive({selector: '[appTest4]' }) export class Test4Directive implements OnInit, OnDestroy{constructor() { }ngOnInit() { console.log("test4 directive ngOnInit")}ngOnDestroy() { console.log("test4 directive ngDestroy");} }

結(jié)果:

說明:

  • 建立一個(gè)directive來 監(jiān)測test1 組件中的 div的生成與銷毀
  • 開始有默認(rèn)的三個(gè)值,所有ngOnInit執(zhí)行了三次
  • 添加一個(gè)值,又執(zhí)行一次ngOnInit
  • 刪除所有的值,執(zhí)行了4次ngDestroy

總結(jié):

  由于生命周期的存在,angular提供了眾多的生命周期的鉤子,讓我們能夠很好的在發(fā)生變化的時(shí)候進(jìn)行處理。

轉(zhuǎn)載于:https://www.cnblogs.com/primadonna/p/9803083.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的Angular 个人深究(四)【生命周期钩子】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。