Использование ViewChild в Angular для доступа к дочернему компоненту, директиве или элементу DOM
Хотите получить доступ к дочернему компоненту, директиве или элементу DOM из родительской компоненты? Это легко сделать с декоратором ViewChild. ViewChild возвращает первый элемент, который соответствует заданному элементу, директиве или шаблону. В случаях, когда вы хотите получить доступ к нескольким дочерним элементам, вместо этого вы должны использовать ViewChildren.
Приятно то, что если эта ссылка будет динамически изменена на новый элемент, ViewChild позаботится о том, чтобы автоматически обновить ее ссылку.
Директивы
Допустим, у нас есть BaconDirective:
import { Directive, ElementRef, Renderer2 } from '@angular/core'; @Directive({ selector: '[appBacon]' }) export class BaconDirective { ingredient = 'mayo'; constructor(elem: ElementRef, renderer: Renderer2) { let bacon = renderer.createText('🥓🥓🥓 '); renderer.appendChild(elem.nativeElement, bacon); } }
И мы используем его в нашем шаблоне компоненты, как на примере ниже, чтобы добавить бекон в наш бутерброд:
<span appBacon>sandwich!</span>
Теперь мы можем получить доступ к директиве с ViewChild с помощью следующего фрагмента в нашем классе компоненты.
В этом примере мы будем обращаться к переменной экземпляра компонента нашей директивы и задавать переменную экземпляра extraIngredient с ее значением:
import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { BaconDirective } from './bacon.directive' @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements AfterViewInit { extraIngredient: string; @ViewChild(BaconDirective) set appBacon(directive: BaconDirective) { this.extraIngredient = directive.ingredient; }; ngAfterViewInit() { console.log(this.extraIngredient); // mayo } }
Здесь мы использовали setter, чтобы установить нашу переменную extraIngredient. Обратите внимание, мы ожидаем, что привязка к жизненному циклу AfterViewInit получит доступ к нашей переменной, так как это делает доступным дочерние компоненты и директивы.
Элементы DOM
Мы можем получить доступ к исходным элементам DOM, которые имеют ссылочную переменную шаблона. Предположим, что у нас в шаблоне есть ссылочная переменная someInput:
<input #someInput placeholder="Your favorite pizza toping">
Мы можем получить доступ к вводу с помощью ViewChild следующим образом:
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 = "Anchovies! 🍕🍕"; } }
И значение нашего инпута будет установлена на "Anchovies! 🍕🍕" при запуске ngAfterViewInit.
Дочерние компоненты
Так же легко получить доступ к дочернему компоненту и вызвать методы или получить доступ к переменным экземпляра потомка. Допустим, у нас есть дочерний компонент с методом whoAmI:
whoAmI() { return '👶 I am a child!!'; }
Затем мы можем вызвать этот метод из нашего родительского компонента с помощью ViewChild следующим образом:
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! } }