Tutorial

Cómo usar ViewChild en Angular para acceder a una directiva, un componente secundario o un elemento DOM

Published on November 23, 2020
Default avatar

By Alligator.io

Español
Cómo usar ViewChild en Angular para acceder a una directiva, un componente secundario o un elemento DOM

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:

  1. 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:

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:

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:

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:

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:

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:

  1. 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á:

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.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Alligator.io

author



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel