一 引言
Angular @ViewChild 装饰器是您在学习 Angular 时会遇到的第一个装饰器之一,因为它也是最常用的装饰器之一。
装饰器@ViewChild是用来获取模板变量的元素的,当组件渲染完成后:
会更新为从dom上找到第一个匹配的组件或指令或纯 HTML 元素。
二 我们什么时候需要@ViewChild 装饰器?
很多时候,我们直接在模板中协调多个自定义组件和 HTML 元素或指令,而无需使用AppComponent类。
但情况并非总是如此!有时,AppComponent 可能需要引用其模板中包含的某些元素,以调解它们的交互。如果是这样,那么我们可以在AppComponent通过查询模板获取对这些模板元素的引用并将它们注入到类中:这就是@ViewChild 的用途。
元数据属性:
selector - 通过选择器(如元素名、指令名或组件名)来指定要查询的元素或指令。
read - 用于从查询到的元素中读取不同的令牌。(至少存在三种令牌:ElementRef、AComponent、SelectDirective)
static - true 以在变更检测运行之前求解查询结果, false 则在变更检测之后求解。默认值为 false。
三 @ViewChild 示例
使用 @ViewChild 注入组件
v层:
<app-demo>this DemoComponent</app-demo>
c层:
export class AppComponent implements OnInit{
@ViewChild(DemoComponent, {static: true})
demo!: DemoComponent;
ngOnInit(): void {
console.log("ngOnInit", this.demo)
}
}
效果:
使用 @ViewChild 注入纯 HTML 元素
v层:
<h2 #demo>对 DOM 元素的引用</h2>
c层:
export class AppComponent implements OnInit{
@ViewChild('demo', {static: true})
demo!: ElementRef;
ngOnInit(): void {
console.log("ngOnInit", this.demo)
}
}
效果:
使用 @ViewChild 注入指令
v层:
<app-demo appMyDirective>this DemoComponent</app-demo>
c层:
export class AppComponent implements OnInit{
@ViewChild(MyDirectiveDirective, {static: true})
demo!: MyDirectiveDirective;
ngOnInit(): void {
console.log("ngOnInit", this.demo)
}
}
效果:四
三 @ViewChild 模板查询的范围是什么?
@ViewChild 的查询范围是当前组件的模板。具体来说,它会查找第一个匹配的元素或指令(除非使用了 {static: false} 选项,这将导致它在 ngAfterViewInit 生命周期钩子中查询,这可能会找到由 *ngFor 或其他结构型指令动态创建的多个元素中的一个)
示例一:
父组件v层
<app-demo appMyDirective>this DemoComponent</app-demo>
子组件v层:
<h2 #demo>demo works!</h2>
在父组件引入子组件的元素:
export class AppComponent implements OnInit{
@ViewChild("demo", {static: true})
demo!: ElementRef;
ngOnInit(): void {
console.log("ngOnInit", this.demo)
}
}
效果:
所以:@ViewChild 的查询范围是当前组件的模板。
四 AfterViewInit 生命周期钩子
调用时机:在Angular完成视图初始化之后,并且所有子组件的视图也已经被初始化之后,AfterViewInit 钩子会被调用。
与 ngOnInit 的区别:ngOnInit 是在Angular完成组件的初始化之后,但在视图渲染之前被调用的。
angular生命周期:
元数据属性:
static - true 以在变更检测运行之前求解查询结果, false 则在变更检测之后求解。默认值为 false。
一下实例分别设置static的值为true和false。
export class AppComponent implements OnInit, AfterViewInit{
@ViewChild(DemoComponent, {static: true})
demo!: DemoComponent;
ngOnInit(): void {
console.log(" ngOnInit demoComponent title", this.demo.title)
}
ngAfterViewInit(): void {
console.log("ngAfterViewInit demoComponent title", this.demo.title);
}
}
static的值设置为true时:
static的值设置为false时:
总结
selector - 通过选择器(如元素名、指令名或组件名)来指定要查询的元素或指令。
read - 用于从查询到的元素中读取不同的令牌。(至少存在三种令牌:通过元素名选择器查询出的元素被包装为ElementRef、通过组件选择查询出来的元素就是组件本身、通过指令选择查询出来的元素就是指令本身)
static - 设置查询时机
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。