[Angular] 笔记 21:@ViewChild

chatgpt:

在 Angular 中,@ViewChild 是一个装饰器,用于在组件类中获取对模板中子元素、指令或组件的引用。它允许你在组件类中访问模板中的特定元素,以便可以直接操作或与其交互。

例如,如果你在模板中有一个子组件或一个具有本地引用的元素,你可以使用 @ViewChild 装饰器在组件类中获取对该元素的引用。这样,你就可以在组件类中调用该元素的方法、访问其属性或者订阅其事件。

这是一个简单的示例,演示了如何在 Angular 组件中使用 @ViewChild

ts 复制代码
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:

html 复制代码
<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:

ts 复制代码
export class PokemonListComponent implements OnInit, AfterViewInit {

完整代码如下:

ts 复制代码
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;
    });
  }
}

3. web 页面:

相关推荐
OpenTiny社区43 分钟前
Coding Agent 到底是怎么工作的,它又为什么会在复杂代码库里失真?
前端·github·agent
奇奇怪怪的1 小时前
Graph RAG:知识图谱增强检索
前端
默_笙1 小时前
🌏 MCP 是 AI 界的 USB-C:一个协议让所有模型都能用上所有工具
前端·javascript
以和为贵1 小时前
🔥前端也能搞懂流式输出:从 SSE 到打字机效果
前端·人工智能·架构
阿成学长_Cain2 小时前
Linux telinit 命令详解:运行级别切换|关机重启|系统维护一站式掌握
linux·运维·前端·网络
Patrick_Wilson2 小时前
最佳实践是有保质期的:从一次 CDN external 白屏事故说起
前端·性能优化·前端工程化
YHHLAI3 小时前
[特殊字符] Agent 智能体开发实战 · 第一课:Tool Use —— 让大模型自动干活
前端·人工智能
nuIl3 小时前
我把 5 个编码 Agent 塞进了一个 npm 包
前端·agent·claude
L-影3 小时前
FastAPI 静态文件:Web 页面的“固定展柜”与“加速引擎”
前端·fastapi
陪我去看海3 小时前
受够了 AI 写完代码留下一堆端口?我做了一个端口管理App!
前端·macos·vibecoding