使用 @ViewChild 和 @ViewChildren 查询 DOM
介绍
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>;
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~