Introducción
Este artículo le introducirá el decorador ViewChild
de Angular.
Es posible que existan situaciones en las que desee acceder a una directiva, componente secundario o elemento DOM de una clase principal de componentes. El decorador ViewChild
devuelve el primer elemento que coincide con una directiva, un componente o un selector de referencia de plantillas concreto.
Uso de ViewChild
con Directivas
ViewChild
hace que sea posible acceder a directivas.
Digamos que tenemos una SharkDirective
.
Idealmente, usará @angular/cli
para generar (generate
) su directiva:
- ng generate directive shark
De lo contrario, es posible que necesite añadirlo manualmente a app.module.ts
:
app.module.ts
import { SharkDirective } from './shark.directive'; ... @NgModule({ declarations: [ AppComponent, SharkDirective ], ... })
Nuestra directiva buscará elementos con el atributo appShark
y preparará el texto en el elemento con la palabra 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); } }
A continuación, añadiremos un Shark
a Fin
usándolo en la plantilla del componente:
app.component.html
<span appShark>Fin!</span>
Cuando visualice la aplicación en un navegador, se mostrará como:
OutputShark Fin!
Ahora, podemos acceder a la variable de la instancia creature
de SharkDirective
y estableceremos una variable de instancia extraCreature
con su 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 un regulador aquí para establecer la variable extraCreature
. Observe que esperamos que el enlace de ciclo de vida AfterViewInit
acceda a nuestra variable, ya que es aquí cuando los componentes y directivas secundarios están disponibles.
Cuando se visualice la aplicación en un navegador, veremos el mensaje "Shark Fin!"
(¡funcionó!). Sin embargo, en el registro de la consola, se mostrará lo siguiente:
OutputDolphin
El componente principal pudo acceder al valor de la directiva.
Uso de ViewChild
con elementos DOM
ViewChild
permite acceder a elementos DOM nativos que tienen una variable de referencia de plantilla.
Digamos que tenemos un <input>
en nuestra plantilla con la variable de referencia #someInput
:
app.component.html
<input #someInput placeholder="Your favorite sea creature">
Ahora podemos acceder a <input>
con ViewChild
y establecer el 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!'; } }
Cuando ngAfterViewInit
active el valor de nuestro <input>
se establecerá a:
OutputWhale!
El componente principal pudo establecer el valor del elemento DOM secundario.
Usar ViewChild
con componentes secundarios
ViewChild
hace que sea posible acceder a un componente secundario y a métodos de invocación o variables de instancia de acceso que están disponibles para el secundario.
Digamos que tenemos un ChildComponent
. Idealmente, usará @angular/cli
para generar (generate
) su componente:
- ng generate component child --flat
Si no es así, es posible que deba crear los archivos child.component.css
y child.component.html
y añadirlos manualmente a app.modul.ts
:
app.module.ts
import { ChildComponent } from './child.component'; ... @NgModule({ declarations: [ AppComponent, ChildComponent ], ... })
Añadiremos un método whoAmI
a ChildComponent
, que devuelve un mensaje:
child.component.ts
whoAmI() { return 'I am a child component!'; }
A continuación, haremos referencia al componente en la plantilla de nuestra aplicación:
app.component.html
<app-child>child works!</app-child>
Ahora podemos invocar el método whoAmI
desde nuestra clase principal de componentes con 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! } }
Cuando se visualiza la aplicación en un navegador, el registro de la consola mostrará:
OutputI am a child component!
El componente principal pudo invocar el método whoAmI
del componente secundario.
Conclusión
Ha aprendido a usar ViewChild
para acceder a una directiva, componente secundario y a un elemento DOM desde una clase principal de componentes.
Si la referencia cambia a un nuevo elemento dinámicamente, ViewChild
actualizará automáticamente su referencia.
En los casos es los que desee acceder a múltiples secundarios, usará ViewChildren
.
Si desea obtener más información sobre Angular, consulte nuestra página sobre el tema Angular para ver ejercicios y proyectos de programación.