Использование 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!
}
}