Angular学习笔记:组件生命周期和自定义指令

本文是自己的学习笔记,主要参考资料如下。

- B站《2020最新Angular实战教程》,老陈打码制作,https://www.bilibili.com/video/BV1i741157Fj?p=2。



  • 1、生命周期
    • 1.1、construct函数
    • 1.2、ngOnChanges
      • 1.2.1、示例
    • 1.3、ngOnInits
    • 1.4、其他hook
  • 2、指令
    • 2.1、使用命令行创建指令
    • 2.2、定义指令接收参数
      • 2.2.1、接收dom元素的参数
      • 2.2.2、接收其他参数
      • 2.2.3、使用指令


1、生命周期

组件中有一些hook可以供我们操控组件,比如组件初始化时,组件数据发生更改时。这些hook都是组件自带的一些方法,方法名都是由ng加上一些名词组成,比如初始化时的ngOnInit,数据更改时ngOnChanges

下面详细介绍各个hook的触发时机。

1.1、construct函数

construct函数不算是hook,但是它发生的时间是在所有hook之前,放在这里比较好记忆。

我们在根页面的ts写下面的代码,在constructor函数中写一个打印信息,
Angular学习笔记:组件生命周期和自定义指令_第1张图片

然后打开根页面,查看打印信息。因为根页面这个组件被加载,所以运行constructor的代码。
在这里插入图片描述


1.2、ngOnChanges

当这个组件有输入时,每次输入进来赋值后就会调用该hook。并且初始化时,会先执行该hook,再执行 ngInit。当然,如果组件没有输入,那该组件从出生到销毁都不会调用该hook。

所谓的输入就是指组件中的@Input()标识的变量。

下面是例子。

1.2.1、示例

新建一个组件app-on-change,在该组件中定义一个输入参数,构造函数,ngChangesngInit

@Component({
  selector: 'app-on-change',
  templateUrl: './on-change.component.html',
  styleUrls: ['./on-change.component.css']
})
export class OnChangeComponent implements OnInit {
  @Input() number;
  constructor() { 
    console.log('onChang component: constructor');

  }
  ngOnChanges(): void {
    console.log('onChang component: ngOnChanges');
  }
  ngOnInit(): void {
    console.log('onChang component: ngOnInit');
  }
}

根组件中引入该组件,将值传入到app-on-change中,并创建一个button,使button每次点击后都会给app-on-change传入新的值,不断地触发其ngOnChangeshook。

html代码


<app-on-change [number]="number">app-on-change>

<button (click)='onClick()'>buttonbutton> 

ts代码

// app.component.ts
export class AppComponent {
  number = 0;
  constructor() {
    console.log("constructor");
  }
  ngOnChanges() {
    console.log("ngOnChanges");
  }
  onClick() {
    this.number++;
  }
}

重启项目,页面打印日志如下
Angular学习笔记:组件生命周期和自定义指令_第2张图片

刚启动时,先执行根页面app-rootconstructor和其他hook。因为根页面没有输入,所以没有触发根页面的ngOnChange的hook。

从第二行开始就执行app-on-changeconstructor和其他hook。

之后我们点击button,修改number的值,使其不断传入组件app-on-change中,不断触发其ngOnChanges的hook。结果如下
Angular学习笔记:组件生命周期和自定义指令_第3张图片



1.3、ngOnInits

组件第一次加载时会调用该hook,要注意的一点是该hook的执行顺序是在ngOnChanges之后。

示例就不写了,可以参考1.2中的内容。


1.4、其他hook

之后的hook暂时先不写,很少用到。所有的hook的执行顺序在官网中有写

Angular官方文档:https://angular.cn/guide/lifecycle-hooks#lifecycle-event-sequence
constructor
ngOnChanges
ngOnInit
ogDoCheck
ngAfterContentInit
ngAfterViewInit
ngAfterViewChecked
ngOnDestroy




2、指令

指令可以理解成普通dom元素的函数,我们可以借助指令自定义dom元素的函数。

比如这里appTestDirective就是一个自定义的指令,它的作用是将h1这个元素的class从原来的2变为abc

<h1 class="'2'" [appTestDirective]="abc">h1h1>

下面就创建一个指令,看看指令的用途。

2.1、使用命令行创建指令

使用ng g directive name创建指令,好处不用多说,和ng g component name一样。

现在创建一个指令ng g directive directive/testDirective。指令结构和component类似,就是没有css文件。Angular学习笔记:组件生命周期和自定义指令_第4张图片

2.2、定义指令接收参数

指令相当于是dom文件的函数,我们需要定义一些参数来接收dom元素和其他一些参数。

2.2.1、接收dom元素的参数

在construct函数中使用依赖注入的方式获取dom元素,并且输入这个dom元素。具体代码如下

@Directive({
  selector: '[appTestDirective]'
})
export class TestDirectiveDirective {
  constructor(public ref: ElementRef) { }
  ngOnChanges() {
    console.log(this.ref);
  }
}

要注意ref的前面要有public,这样依赖注入进来的ref才能在constructor函数以外使用。

这种依赖注入的方式不仅可以在指令中使用,也可以在组件中使用。

这里先写到这里,等会将指令使用到具体的dom元素中再看看ref的内容是什么。

2.2.2、接收其他参数

这类参数是用来辅助的。定义方式和在组件中定义普通的输入类似。

@Directive({
  selector: '[appTestDirective]'
})
export class TestDirectiveDirective {
  @Input() appTestDirective;
  constructor(public ref: ElementRef) { }
  ngOnChanges() {
    console.log(this.ref);
  }
}

要注意,这个输入的名字必须和指令的selector一样,但不要其中的中括号。

2.2.3、使用指令

我们在app.component.html中使用指令。使用

来搭配指令。

<h1 class="'2'" [appTestDirective]="abc">h1h1>

其中,abc是app.component.ts中定义的一个变量。

export class AppComponent {
  abc = 'class';
}

这段话可以理解成appTestDirective是我们自定义的一个事件,在这个事件对应的逻辑中我们可以获取dom元素和一些额外的参数进行操作。

之后我们在指令中写入一些逻辑来改变h1元素的类名。

export class TestDirectiveDirective {
  @Input() appTestDirective;
  constructor(public ref: ElementRef) { }
  ngOnChanges() {
    console.log(this.ref);
    this.ref.nativeElement.className = this.appTestDirective;
  }
}

h1的类名原本是2,但上面代码通过指令将其类名改成了变量abc的值,即class

我们打开主页面,发现h1的类名确实改变了。Angular学习笔记:组件生命周期和自定义指令_第5张图片

你可能感兴趣的:(Angular,angular.js)