本文共 3248 字,大约阅读时间需要 10 分钟。
本文是自己的学习笔记,主要参考资料如下。
- B站《2020最新Angular实战教程》,老陈打码制作,https://www.bilibili.com/video/BV1i741157Fj?p=2。
组件中有一些hook可以供我们操控组件,比如组件初始化时,组件数据发生更改时。这些hook都是组件自带的一些方法,方法名都是由ng
加上一些名词组成,比如初始化时的ngOnInit
,数据更改时ngOnChanges
。
下面详细介绍各个hook的触发时机。
construct函数不算是hook,但是它发生的时间是在所有hook之前,放在这里比较好记忆。
我们在根页面的ts写下面的代码,在constructor函数中写一个打印信息,
然后打开根页面,查看打印信息。因为根页面这个组件被加载,所以运行constructor的代码。
当这个组件有输入时,每次输入进来赋值后就会调用该hook。并且初始化时,会先执行该hook,再执行 ngInit
。当然,如果组件没有输入,那该组件从出生到销毁都不会调用该hook。
所谓的输入就是指组件中的@Input()
标识的变量。
下面是例子。
新建一个组件app-on-change
,在该组件中定义一个输入参数,构造函数,ngChanges
和ngInit
。
@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
传入新的值,不断地触发其ngOnChanges
hook。
html
代码
ts
代码
// app.component.tsexport class AppComponent { number = 0; constructor() { console.log("constructor"); } ngOnChanges() { console.log("ngOnChanges"); } onClick() { this.number++; }}
重启项目,页面打印日志如下
刚启动时,先执行根页面app-root
的constructor
和其他hook。因为根页面没有输入,所以没有触发根页面的ngOnChange
的hook。
从第二行开始就执行app-on-change
的constructor
和其他hook。
之后我们点击button,修改number
的值,使其不断传入组件app-on-change
中,不断触发其ngOnChanges
的hook。结果如下
组件第一次加载时会调用该hook,要注意的一点是该hook的执行顺序是在ngOnChanges
之后。
示例就不写了,可以参考1.2
中的内容。
之后的hook暂时先不写,很少用到。所有的hook的执行顺序在官网中有写
指令可以理解成普通dom元素的函数,我们可以借助指令自定义dom元素的函数。
下面就创建一个指令,看看指令的用途。
使用ng g directive name
创建指令,好处不用多说,和ng g component name
一样。
现在创建一个指令ng g directive directive/testDirective
。指令结构和component类似,就是没有css文件。
指令相当于是dom文件的函数,我们需要定义一些参数来接收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的内容是什么。
这类参数是用来辅助的。定义方式和在组件中定义普通的输入类似。
@Directive({ selector: '[appTestDirective]'})export class TestDirectiveDirective { @Input() appTestDirective; constructor(public ref: ElementRef) { } ngOnChanges() { console.log(this.ref); }}
要注意,这个输入的名字必须和指令的selector一样,但不要其中的中括号。
我们在app.component.html
中使用指令。使用<h1>
来搭配指令。
h1
其中,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的类名确实改变了。
转载地址:http://hswsi.baihongyu.com/