Table of Contents
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:
[label 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:
[label 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:
[label app.component.html]
<span <^>appShark<^>>Fin!</span>
Cuando visualice la aplicación en un navegador, se mostrará como:
[secondary_label Output]
Shark Fin!
Ahora, podemos acceder a la variable de la instancia creature de SharkDirective y estableceremos una variable de instancia extraCreature con su valor:
[label 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:
[secondary_label Output]
Dolphin
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:
[label app.component.html]
<input <^>#someInput<^> placeholder="Your favorite sea creature">
Ahora podemos acceder a <input> con ViewChild y establecer el valor:
[label 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:
[secondary_label Output]
Whale!
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:
[label app.module.ts]
<^>import { ChildComponent } from './child.component';<^>
...
@NgModule({
declarations: [
AppComponent,
<^>ChildComponent<^>
],
...
})
Añadiremos un método whoAmI a ChildComponent, que devuelve un mensaje:
[label child.component.ts]
whoAmI() {
return 'I am a child component!';
}
A continuación, haremos referencia al componente en la plantilla de nuestra aplicación:
[label app.component.html]
<app-child>child works!</app-child>
Ahora podemos invocar el método whoAmI desde nuestra clase principal de componentes con ViewChild
[label 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á:
[secondary_label Output]
I 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.