在 Angular 中使用 ViewChild 访问子组件、指令或 DOM 元素的操作方法

 更新时间:2024年08月12日 09:53:12   作者:白如意i  
这篇文章主要介绍了如何在 Angular 中使用 ViewChild 来访问子组件、指令或 DOM 元素,在本教程中,您使用了 ViewChild 来从父组件类中访问指令、子组件和 DOM 元素,需要的朋友可以参考下

简介

本文将向您介绍 Angular 的 ViewChild 装饰器。

在某些情况下,您可能希望从父组件类中访问指令、子组件或 DOM 元素。ViewChild 装饰器返回与给定指令、组件或模板引用选择器匹配的第一个元素。

先决条件

如果您想要跟随本教程进行操作:

  • 考虑安装 @angular/cli
  • 使用 @angular/cli 创建一个新项目,以测试 ViewChild 在其中的功能。

本教程已经验证过可以在 @angular/core v13.0.2 和 @angular/cli v13.0.3 下使用。

使用 ViewChild 与指令

ViewChild 使得访问指令成为可能。

假设您有一个 SharkDirective。该指令将查找具有属性 appShark 的元素,并在元素的文本前面添加单词 "Shark"

理想情况下,您将使用 @angular/cligenerate 您的指令:

ng generate directive shark --skip-tests

此命令将创建一个 shark.directive.ts 文件,并将该指令添加到 app.module.ts

import { SharkDirective } from './shark.directive';
...
@NgModule({
  declarations: [
    AppComponent,
    SharkDirective
  ],
  ...
})

然后,使用 ElementRefRenderer2 来重写文本。将 shark.directive.ts 的内容替换为以下内容:

import {
  Directive,
  ElementRef,
  Renderer2
} from '@angular/core';
@Directive(
  { selector: '[appShark]' }
)
export class SharkDirective {
  creature = 'Dolphin';
  constructor(elem: ElementRef, renderer: Renderer2) {
    let shark = renderer.createText('Shark ');
    renderer.appendChild(elem.nativeElement, shark);
  }
}

接下来,在组件模板中的一个包含文本的 span 中添加一个 appShark 属性。将 app.component.html 的内容替换为以下内容:

<span appShark>Fin!</span>

在浏览器中查看应用程序时,将在元素的内容之前呈现单词 "Shark"

Shark Fin!

现在,您还可以访问 SharkDirectivecreature 实例变量,并使用其值设置一个 extraCreature 实例变量。将 app.component.ts 的内容替换为以下内容:

import {
  Component,
  ViewChild,
  AfterViewInit
} from '@angular/core';
import { SharkDirective } from './shark.directive';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  extraCreature!: string;
  @ViewChild(SharkDirective)
  set appShark(directive: SharkDirective) {
    this.extraCreature = directive.creature;
  };
  ngAfterViewInit() {
    console.log(this.extraCreature); // Dolphin
  }
}

此代码使用了一个 setter 来设置 extraCreature 变量。请注意,它等待 AfterViewInit 生命周期钩子来访问变量,因为这是子组件和指令可用的时候。

在浏览器中查看应用程序时,您仍将看到 "Shark Fin!" 消息。但是,在控制台日志中,它将显示:

Dolphin

父组件能够访问指令的值。

使用 ViewChild 与 DOM 元素

ViewChild 使得访问具有模板引用变量的本机 DOM 元素成为可能。

假设您在模板中有一个带有 #someInput 引用变量的 <input>。将 app.component.html 的内容替换为以下内容:

<input #someInput placeholder="Your favorite sea creature">

现在,您可以使用 ViewChild 访问 <input> 并设置 value。将 app.component.ts 的内容替换为以下内容:

import {
  Component,
  ViewChild,
  AfterViewInit,
  ElementRef
} from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild('someInput') someInput!: ElementRef;
  ngAfterViewInit() {
    this.someInput.nativeElement.value = 'Whale!';
  }
}

ngAfterViewInit 触发时,<input> 的值将被设置为:

Whale!

父组件能够设置子 DOM 元素的值。

使用 ViewChild 与子组件

ViewChild 使得访问子组件并调用子组件可用的方法或访问实例变量成为可能。

假设您有一个 PupComponent

理想情况下,您将使用 @angular/cligenerate 您的组件:

ng generate component pup --flat --skip-tests

此命令将创建 pup.component.tspup.component.csspup.component.html 文件。并将该组件添加到 app.module.ts

import { PupComponent } from './pup.component';
...
@NgModule({
  declarations: [
    AppComponent,
    PupComponent
  ],
  ...
})

然后,在 PupComponent 中添加一个返回消息的 whoAmI 方法:

import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-pup',
  templateUrl: './pup.component.html',
  styleUrs: ['./pup/component.css']
})
export class PupComponent implements OnInit {
  constructor() { }
  whoAmI() {
    return 'I am a pup component!';
  }
  ngOnInit(): void {
  }
}

接下来,在应用程序模板中引用子组件。将 app.component.html 的内容替换为以下内容:

<app-pup>pup works!</app-pup>

现在,您可以使用 ViewChild 在父组件类中调用 whoAmI 方法。将 app.component.ts 的内容替换为以下内容:

import {
  Component,
  ViewChild,
  AfterViewInit
} from '@angular/core';
import { PupComponent } from './pup.component';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements AfterViewInit {
  @ViewChild(PupComponent) pup!: PupComponent;
  ngAfterViewInit() {
    console.log(this.pup.whoAmI()); // I am a pup component!
  }
}

在浏览器中查看应用程序时,控制台日志将显示:

I am a pup component!

父组件能够调用子组件的 whoAmI 方法。

结论

在本教程中,您使用了 ViewChild 来从父组件类中访问指令、子组件和 DOM 元素。

如果引用动态更改为新元素,ViewChild 将自动更新其引用。

在需要访问多个子元素的情况下,您应该使用 ViewChildren

如果您想了解更多关于 Angular 的知识,请查看我们的 Angular 专题页面,了解练习和编程项目。

到此这篇关于在 Angular 中使用 ViewChild 访问子组件、指令或 DOM 元素的操作方法的文章就介绍到这了,更多相关Angular 使用 ViewChild 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法

    后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法

    这篇文章主要介绍了后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法的相关资料,需要的朋友可以参考下
    2016-07-07
  • Angular 服务器端渲染错误消息localStorage is not defined解决分析

    Angular 服务器端渲染错误消息localStorage is not defined解决分析

    这篇文章主要为大家介绍了Angular 服务器端渲染错误消息localStorage is not defined解决分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • AngularJS动态生成div的ID源码解析

    AngularJS动态生成div的ID源码解析

    这篇文章主要介绍了基于AngularJS动态生成div的ID,本文介绍的非常详细,具有参考借鉴价值,对angularjs动态生成div的id相关知识感兴趣的朋友一起学习吧
    2016-08-08
  • AngularJS实践之使用NgModelController进行数据绑定

    AngularJS实践之使用NgModelController进行数据绑定

    大家都知道AngularJS中的指令是其尤为复杂的一个部分,但是这也是其比较好玩的地方。这篇文章我们就来说一说如何在我们自定义的指令中,利用ngModel的controller来做双向数据绑定,本文对大家学习AngularJS具有一定的参考借鉴价值,有需要的朋友们可以参考借鉴。
    2016-10-10
  • 详解angular2实现ng2-router 路由和嵌套路由

    详解angular2实现ng2-router 路由和嵌套路由

    本篇文章主要介绍了详解angular2实现ng2-router 路由和嵌套路由,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • angularjs基础教程

    angularjs基础教程

    AngularJS是为了克服HTML在构建应用上的不足而设计的。HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了。所以我做了一些工作(你也可以觉得是小花招)来让浏览器做我想要的事。
    2014-12-12
  • 使用yeoman构建angular应用的方法

    使用yeoman构建angular应用的方法

    下面小编就为大家带来一篇使用yeoman构建angular应用的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Angular4如何自定义首屏的加载动画详解

    Angular4如何自定义首屏的加载动画详解

    Angular应用程序在首次加载根组件时会在浏览器的显示一个loading...动画,下面这篇文章主要给大家介绍了关于Angular4如何自定义首屏加载动画的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编来一起看看吧。
    2017-07-07
  • AngularJS 避繁就简的路由

    AngularJS 避繁就简的路由

    这篇文章主要为大家详细介绍了AngularJS 避繁就简的路由的相关资料,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Angular多选、全选、批量选择操作实例代码

    Angular多选、全选、批量选择操作实例代码

    列表批量选择是一个开发人员经常遇到的功能,列表批量选择的实现方式很多,这篇文章主要介绍了Angular多选、全选、批量选择实例代码,有兴趣的可以了解一下。
    2017-03-03

最新评论