chatgpt:
在 Angular 中,@ViewChild
是一个装饰器,用于在组件类中获取对模板中子元素、指令或组件的引用。它允许你在组件类中访问模板中的特定元素,以便可以直接操作或与其交互。
例如,如果你在模板中有一个子组件或一个具有本地引用的元素,你可以使用 @ViewChild
装饰器在组件类中获取对该元素的引用。这样,你就可以在组件类中调用该元素的方法、访问其属性或者订阅其事件。
这是一个简单的示例,演示了如何在 Angular 组件中使用 @ViewChild
:
import { Component, ViewChild, ElementRef } from '@angular/core';@Component({selector: 'app-example',template: `<div #myElement>Some content</div>`
})
export class ExampleComponent {@ViewChild('myElement', { static: true }) myElementRef: ElementRef;ngAfterViewInit() {// 可以在这里访问和操作子元素console.log(this.myElementRef.nativeElement.textContent); // 获取子元素的文本内容this.myElementRef.nativeElement.style.color = 'red'; // 修改子元素的样式}
}
在这个例子中,@ViewChild
装饰器用于获取模板中带有 #myElement
本地引用的 <div>
元素的引用,并在 ngAfterViewInit
生命周期钩子中对其进行操作。
需要注意的是,@ViewChild
装饰器接受一个选择器作为参数,用于定位模板中的元素。在这里,我们使用了 #myElement
选择器来获取对应的元素引用。
另外,{ static: true }
是 @ViewChild
的一个配置选项,用于指定何时应该去查询视图中的元素。{ static: true }
表示在组件初始化时就会进行查询,{ static: false }
表示在首次调用 ngAfterViewInit
生命周期钩子时进行查询。
Angular For Beginners - 25. @ViewChild()
当使用 JavaScript 时,可以使用 getElementById
来获取特定的 HTML 元素对象。但在 Angular 中,并没有类似于 getElementById
的直接函数。相反,Angular 提供了 @ViewChild
这样的装饰器,用于在组件类中获取模板中特定元素的引用,从而实现类似的功能。
但是,getElementById
的参数与 @ViewChild
的参数有很大的不同。 不能传 html 标签或 css 选择器给 @ViewChild
,传进 @ViewChild
中的参数分以下 4 种:
1.
pokemon-list.compoment.html
增加一个 template ref #pokemonRef
:
<table><thead><th>Name</th><th>Index</th></thead><tbody><app-pokemon-detail#pokemonRef // new code*ngFor="let pokemon of pokemons"[detail]="pokemon"(remove)="handleRemove($event)"><h1>-----------------------</h1><h2>============================</h2><h3></h3></app-pokemon-detail></tbody>
</table>
2.
多个孩子用 @ViewChildren
,单个用 @ViewChild
。
@ViewChild
只能在 View 渲染之后才能使用:
pokemon-list.compoment.ts
:
因为 ngAfterViewInit
继承了 AfterViewInit
, 所以 PokemonListComponent
需要 implement AfterViewInit
:
export class PokemonListComponent implements OnInit, AfterViewInit {
完整代码如下:
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild, ViewChildren } from '@angular/core';
import { Pokemon } from 'src/app/models/pokemon';
import { PokemonService } from 'src/app/services/pokemon.service';@Component({selector: 'app-pokemon-list',templateUrl: './pokemon-list.component.html',styleUrls: ['./pokemon-list.component.css'],
})
export class PokemonListComponent implements OnInit, AfterViewInit {// pokemons!: Pokemon[];pokemons: Pokemon[] = [];// 这里不是 @ViewChild, 否则log 为 undefined// 而是 @ViewChildren,使用了 for 循环, 孩子数多于一个,有3个。@ViewChildren('pokemonRef') pokemonRef!: ElementRef;constructor(private pokemonService: PokemonService) {}// 新代码ngAfterViewInit(): void {// throw new Error('Method not implemented.');console.log("ngAfterViewInit begin")console.log(this.pokemonRef)console.log("ngAfterViewInit end")}handleRemove(event: Pokemon) {this.pokemons = this.pokemons.filter((pokemon: Pokemon) => {return pokemon.id !== event.id;});}ngOnInit(): void {// 填充 pokemons 属性// this.pokemons = this.pokemonService.getPokemons();this.pokemonService.getPokemons().subscribe((data: Pokemon[]) => {console.log(data);this.pokemons = data;});}
}