使用 @ViewChild 和 @ViewChildren 查询 DOM

发布日期:2026-07-10 18:39:06   来源 : 杭州电子商务研究院    浏览量 :16
杭州电子商务研究院 发布日期:2026-07-10 18:39:06  
16

介绍

DOM 操作负责修改现有 DOM 元素并更改其当前外观或行为。您可能还需要修改应用程序的其他重要部分,例如组件、指令和其他 DOM 元素。ViewChild和 ViewChildren用于在组件之间进行通信以访问数据。

@ViewChild@ViewChildren是用于访问子组件类及其不同属性到父组件的装饰器类型。它类似于继承。

让我们更详细地了解每一个。

Angular 中的 @ViewChild 是什么?

@ViewChild 装饰器用于从 DOM 树中查询单个 DOM 元素并允许您对其进行操作。要从模板中选择一个元素,可以使用三个不同的参数。

  • Selector:要查询的元素的选择器。它可以是指令类型或名称。
  • 读取:从查询元素中读取不同的标记。
  • 静态:这是 Angular 8 中引入的新功能之一,它表示是否在变更检测运行之前解析查询结果。

让我们看一个如何使用@ViewChild装饰器的例子。

首先,使用下面的ng命令创建除应用程序组件之外的新组件。

      Ng generate component democomponent
    

演示组件.组件.html

      <div>
    This is {{ componentName }} component
</div>
    

这里我们使用了在组件类中声明的本地输入变量,以打印来自父组件的值。

在组件中声明@Input变量,如下所示。

      import { Component, OnInit, Input } from "@angular/core";

@Component({
  selector: "app-democomponent",
  templateUrl: "./democomponent.component.html",
  styleUrls: ["./democomponent.component.css"]
})

export class DemocomponentComponent implements OnInit {

  // To get component name from app component
  @Input() componentName: string;
  constructor() {}
}
    

我们已经完成了演示组件。现在,我们将使用我们之前创建的子组件并对其进行操作。

应用程序.组件.html

      <app-democomponent componentName="DEMO">

</app-democomponent>
    

如果您注意到,我们已经使用了附加属性以及子组件选择器,即componentName=DEMO

应用程序.组件.ts

      import { Component, ViewChild } from "@angular/core";
import { DemocomponentComponent } from "./democomponent/democomponent.component";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})

export class AppComponent {
  name = "Angular";

  // Getting the reference
  @ViewChild(DemocomponentComponent, { static: false }) hello: DemocomponentComponent;
  ngAfterViewInit() {
     console.log("Hello ", this.hello.componentName);
  }
}
    

我们可以使用“hello”变量直接访问子组件的属性。

      ngAfterViewInit() {
  console.log("Hello ", this.hello.componentName);
}
    

请注意,我们使用了ngAfterViewInit()钩子。你可能会问,为什么?当应用程序加载时,子元素可能未完全加载,如果我们尝试访问该组件,它会返回未定义。为了解决这个问题,我们使用了生命周期钩子,它允许我们在视图初始化后访问任何元素。

我们还可以使用@ViewChild访问任何特定元素,而不是引用整个组件,这是我们迄今为止所做的。用下面的代码替换代码。

      import { Component, ViewChild, ElementRef  } from "@angular/core";
import { DemocomponentComponent } from "./democomponent/democomponent.component";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})

export class AppComponent {
  name = "Angular";
  // Getting the reference of the button control
  @ViewChild("myButton", { static: false }) myButton: ElementRef;

  ngAfterViewInit() {
   console.log("Hello ", this.myButton.nativeElement);
  }
}
    

我们所做的改变是,按钮控制元素现在是我们在 HTML 中使用的元素。

应用程序.组件.html

      <div>
 <button type="button" #myButton>My Button</button>
</div>
    

要访问原生元素,我们可以使用ElementRef,它返回原生 HTML 元素。可以从组件中像这样访问它:

      @ViewChild("myButton", { static: false }) myValue: ElementRef;
    

它可以使用ngAfterViewInit()访问原生元素,如下所示:

      ngAfterViewInit() {
    console.log("Hello ", this.myValue.nativeElement);
}
    

上述示例的输出将如下所示:

正如您在控制台中的上述输出中看到的那样,我们获得了作为原生元素的响应,因为ElementRef根据与@ViewChild一起获取的引用返回了原生元素。

因此,我们可以尝试上述任何一种方法从模板访问子元素或本机元素。

Angular 中的 @ViewChildren 是什么?

@ViewChild不同,@ViewChildren装饰器用于访问多个元素。元素列表的响应始终是QueryList

每当在 HTML DOM 树中添加、更新或删除任何子元素时,QueryList 将始终更新

让我们看一个例子来更好地了解@ViewChildren的工作原理。

使用以下ng命令创建一个新组件。

      Ng generate component hello
    

你好.组件.html

      <div>
    <h1>Hello {{name}}!</h1> 
</div>
    

你好.component.ts

      import { Component, Input } from '@angular/core';

@Component({
  selector: "hello",
  templateUrl: "./hello.component.html",
  styleUrls: ["./hello.component.css"]
})

export class HelloComponent  {
  @Input() name: string;
}
    

在这个组件中,@Input装饰器用于从父组件获取值。

让我们深入挖掘并在一个简单的示例中将QueryList@ViewChildren一起使用。

应用程序.组件.html

      <hello name="{{ name }}"></hello>

<hello name="{{ name }}"></hello>

<hello name="{{ name }}"></hello>
    

如您所见,我们已经使用了选择器三次以及名称属性。现在让我们尝试使用@ViewChildren访问它,如下所示。

应用程序.组件.ts

      import {
 Component,
 ViewChildren,
 AfterViewInit,
 QueryList
} from "@angular/core";
import { HelloComponent } from "./hello.component";

@Component({
 selector: "my-app",
 templateUrl: "./app.component.html",
 styleUrls: ["./app.component.css"]
})

export class AppComponent implements AfterViewInit {

 name = "Angular";

 // Accessing multiple native DOM elements using QueryList
 @ViewChildren(HelloComponent) myValue: QueryList<HelloComponent>;

 ngAfterViewInit() {
     console.log("Hello ", this.myValue);
 }

}
    

在此组件中,我们需要通过引用子组件使用@ViewChildren访问多个原生 DOM 元素,如下所示。

      @ViewChildren(HelloComponent) myValue: QueryList<HelloComponent>;
    
以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据