Introdução
Este artigo irá apresentar-lhe o decorador ViewChild
do Angular.
Pode haver situações em que seja desejável acessar uma diretiva, componente filho ou um elemento DOM de uma classe de componentes pai. O decorador ViewChild
retorna o primeiro elemento que corresponde a um determinado componente, diretiva ou seletor de referência modelo.
O ViewChild
torna possível acessar diretivas.
Vamos supor que temos uma SharkDirective
.
Idealmente, você irá usar @angular/cli
para generate
(gerar) sua diretiva:
- ng generate directive shark
Caso contrário, pode ser necessário adicioná-la manualmente ao app.module.ts
:
app.module.ts
import { SharkDirective } from './shark.directive';
...
@NgModule({
declarations: [
AppComponent,
SharkDirective
],
...
})
Nossa diretiva irá procurar elementos com o atributo appShark
e anexar a palavra Shark
no início do texto no elemento:
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);
}
}
Em seguida, vamos adicionar um Shark
em Fin
usando ele no modelo de componente:
app.component.html
<span appShark>Fin!</span>
Ao visualizar o aplicativo em um navegador, ele será exibido como:
Output
Shark Fin!
Agora, vamos acessar a variável de instância creature
de SharkDirective
e definir uma variável de instância extraCreature
com o seu valor:
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
}
}
Usamos um setter aqui para definir a variável extraCreature
. Observe que esperamos o gancho de ciclo de vida AfterViewInit
acessar nossa variável, pois é neste momento em que os componentes filhos e diretivas ficam disponíveis.
Ao visualizar o aplicativo em um navegador, ainda vamos ver o "Shark Fin!"
como mensagem. No entanto, no registro do console, será exibido:
Output
Dolphin
O componente pai foi capaz de acessar o valor da diretiva.
O ViewChild
torna possível acessar elementos DOM nativos que possuem uma variável de referência modelo.
Vamos supor que temos um <input>
em nosso modelo com a variável de referência #someInput
:
app.component.html
<input #someInput placeholder="Your favorite sea creature">
Agora, podemos acessar o <input>
com o ViewChild
e definir o value
(valor):
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!";
}
}
Quando o ngAfterViewInit
disparar, o valor de nosso <input>
será definido como:
Output
Whale!
O componente pai foi capaz de definir o valor do elemento DOM filho.
O ViewChild
torna possível acessar um componente filho e chamar métodos ou acessar variáveis de instância que estão disponíveis para o filho.
Vamos supor que temos um ChildComponent
. Idealmente, você irá usar @angular/cli
com a opção generate
para criar seu componente:
- ng generate component child --flat
Caso contrário, pode ser necessário criar os arquivos child.component.css
e child.component.html
e adicioná-los manualmente ao app.module.ts
:
app.module.ts
import { ChildComponent } from './child.component';
...
@NgModule({
declarations: [
AppComponent,
ChildComponent
],
...
})
Vamos adicionar um método whoAmI
ao ChildComponent
que retorna uma mensagem:
child.component.ts
whoAmI() {
return 'I am a child component!';
}
Em seguida, vamos referenciar o componente em nosso modelo de aplicativo:
app.component.html
<app-child>child works!</app-child>
Agora, chamamos o método whoAmI
de dentro da nossa classe de componentes pai com o ViewChild
, desta maneira:
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!
}
}
Ao visualizar o aplicativo em um navegador, o registro do console irá exibir:
Output
I am a child component!
O componente pai foi capaz de chamar o método whoAmI
do componente filho.
Conclusão
Você aprendeu a usar o ViewChild
para acessar um componente filho, diretiva e um elemento DOM de uma classe de componentes pai.
Se a referência mudar dinamicamente para um novo elemento, o ViewChild
irá atualizar sua referência automaticamente.
Em casos em que você deseja acessar vários filhos, deve usar então o ViewChildren
.
Se você gostaria de aprender mais sobre o Angular, confira nossa página de tópico sobre Angular para exercícios e projetos de programação.