如何在 Angular 中使用 ViewChild 访问子组件、指令或 DOM 元素

介绍

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

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

ViewChild与指令一起使用

ViewChild 使访问指令成为可能。

假设我们有一个SharkDirective.

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

  • ng generate directive shark

否则,您可能需要手动将其添加到app.module.ts

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

我们的指令将查找具有属性的元素,appShark并在元素的文本前加上单词Shark

鲨鱼指令.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);
  }
}

接下来,我们将通过在组件模板中使用它Shark添加一个Fin

应用程序组件.html
<span appShark>Fin!</span>

在浏览器中查看应用程序时,它将显示为:

Output
Shark Fin!

现在,我们可以访问creature实例变量SharkDirectiveextraCreature使用其值设置实例变量:

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!"消息。但是,在控制台日志中,它将显示:

Output
Dolphin

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

使用ViewChild与DOM元素

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

假设<input>我们的模板中有一个带有#someInput引用变量的变量:

应用程序组件.html
<input #someInput placeholder="Your favorite sea creature">

现在,我们可以访问<input>withViewChild并设置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>的值设置为:

Output
Whale!

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

使用ViewChild与子组件

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

假设我们有一个ChildComponent. 理想情况下,你会使用@angular/cligenerate您的组件:

  • ng generate component child --flat

否则,您可能需要创建child.component.csschild.component.html文件并将其手动添加到app.module.ts

app.module.ts
import { ChildComponent } from './child.component';
...
@NgModule({
  declarations: [
    AppComponent,
    ChildComponent
  ],
  ...
})

我们将添加whoAmI到方法ChildComponent返回一个信息:

子组件.ts
whoAmI() {
  return 'I am a child component!';
}

接下来,我们将在我们的应用程序模板中引用该组件:

应用程序组件.html
<app-child>child works!</app-child>

现在,我们可以whoAmI从父组件类中调用该方法,ViewChild如下所示:

app.component.ts
import {
  Component,
  ViewChild,
  AfterViewInit
} from '@angular/core';
import { ChildComponent } from './child.component';

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

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

Output
I am a child component!

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

结论

您已经学会了如何ViewChild从父组件类访问指令、子组件和 DOM 元素。

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

如果您想访问多个子项,则可以ViewChildren改用。

如果您想了解有关 Angular 的更多信息,请查看我们的 Angular 主题页面以获取练习和编程项目。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁