Введение
В этой статье мы познакомим вас с декоратором Angular ViewChild
.
В некоторых ситуациях вам может потребоваться доступ к директиве, дочернему компоненту или элементу DOM из класса родительского компонента. Декоратор ViewChild
возвращает первый элемент, совпадающий с заданной директивой, компонентом или селектором шаблонов.
Использование ViewChild
с директивами
ViewChild
открывает возможность доступа к директивам.
Допустим, у нас имеется директива SharkDirective
.
В идеале мы используем @angular/cli
для генерирования
директивы:
- ng generate directive shark
В противном случае необходимо добавить ее вручную в app.module.ts
:
app.module.ts
import { SharkDirective } from './shark.directive';
...
@NgModule({
declarations: [
AppComponent,
SharkDirective
],
...
})
Наша директива будет искать элементы с атрибутом appShark
и добавлять в начало текста элемента слово Shark
:
shark.directive.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
, используя его в шаблоне компонента:
app.component.html
<span appShark>Fin!</span>
При просмотре приложения в браузере оно будет выглядеть так:
Output
Shark Fin!
Теперь мы можем получить доступ к переменной экземпляра creature
директивы SharkDirective
и задать переменную экземпляра extraCreature
с ее значением:
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
}
}
Здесь мы использовали задающий метод, чтобы задать переменную extraCreature
. Обратите внимание, что мы ждем, пока блок жизненного цикла AfterViewInit
не получит доступ к нашей переменной, поскольку тогда станут доступными дочерние компоненты и директивы.
При просмотре приложения в браузере мы видим "Shark Fin!"
, сообщение. Однако в журнале консоли отображается следующее:
Output
Dolphin
Родительскому компоненту удалось получить доступ к значению из директивы.
Использование ViewChild
с элементами DOM
ViewChild
предоставляет возможность доступа к элементам модели DOM, имеющим шаблонную переменную.
Допустим в нашем шаблоне имеется <input>
с шаблонной переменной #someInput
:
app.component.html
<input #someInput placeholder="Your favorite sea creature">
Теперь мы можем получить доступ к <input>
с помощью ViewChild
и задать значение
:
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/cli
для генерирования
компонента:
- ng generate component child --flat
В противном случае вам может понадобиться создать файлы child.component.css
и child.component.html
и вручную добавить их в app.module.ts
:
app.module.ts
import { ChildComponent } from './child.component';
...
@NgModule({
declarations: [
AppComponent,
ChildComponent
],
...
})
Мы добавим метод whoAmI
в компонент ChildComponent
, который возвращает следующее сообщение:
child.component.ts
whoAmI() {
return 'I am a child component!';
}
Далее мы разместим ссылку на компонент в нашем шаблоне приложения:
app.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, где вы найдете упражнения и проекты по программированию.