Reference DOM elements with Angular ViewChild Decorator

0

The SeeChild decorator is the recommended way to access a directive, child component, or DOM element from a parent component class in Angular applications. Of course you can use document.getElementByID () or a similar JavaScript selector, but there are a few good reasons why it’s not a good idea:

  1. It goes against Angular’s component-based architecture by going beyond component boundaries and grabbing an exterior element.
  2. Being reusable, the model elements of a component do not have to have an ID to begin with. If you add one to use document.getElementById (), you may be preparing for bugs.
  3. Ultimately, SeeChild gives you the ability to read elements as different types of objects, which plays a vital role in component interactions.

To that end, this tutorial will cover the SeeChild the many features of the decorator as well as some of the many ways to use it.

Read: Interaction of parent-child components in Angular.

Swap ViewChild for document.getElementById ()

Here is a variation of Hi world which allows the user to provide their name via a text entry field:





{{greeting}}

Clicking on the Submit button triggers the say hi() method. Here, document.getElementById () is used to get a reference to the txt input control:

export class AppComponent {
  public greeting = '';
  
  public setGreeting() {
    this.greeting = 'Hello ' + document.getElementById('txtWhoAreYou').value + '!';
  }
}

The greeting the variable is then updated in the model:

Now, let’s compare this to the correct way to reference DOM elements using the SeeChild decorator. It returns the first element that matches a given directive, component, or model reference selector:

export class AppComponent {
  public greeting = '';
  
  @ViewChild('whoAreYou') 
  private whoAreYouRef: ElementRef;
 
  public setGreeting() {
    this.greeting = 'Hello ' + this.whoAreYouRef.nativeElement.value + '!';
  }
}

By default, DOM elements are stored as ElementRef type. It just acts as a wrapper for the native DOM element, and we can grab it by accessing the native element goods. He has a type of all, but you can convert it to the correct item type if you want its methods and properties to appear in VS Code’s autocomplete:

DOM elements in JavaScript and Angular

SEO components

SeeChild can also help us access child components – both from Angular (i.e. Material) and custom libraries. The secret lies in See the children second argument. It is an object that contains the properties of metadata:

  • selector: The type of component / directive or the name used for the query.
  • read: Used to read a different type of queried items.
  • static: True to resolve query results before running change detection, false to be solved after detection of change. The default value is false.

Setting the See the children read property to one MatButton allows us to access its class properties and methods:

export class GreetComponent  {
  @ViewChild('submitButton', { read: MatButton })
  public submitButton: MatButton
  
  //...
}

For example, after defining the submit button variable as public, we can reference it from the template to set the focus on the Submit button whenever the Enter key is pressed in the input field:


Referencing a custom component

We can also use SeeChild to access members of the public class of a child component. In this case, we do not have to provide any additional parameters. As long as there is only one instance of the class in the model, we can reference it by name, as seen here in the AppComponent:

export class AppComponent implements AfterViewInit {
  @ViewChild(GreetComponent) greetComponent: GreetComponent;

  ngAfterViewInit(): void {
    this.greetComponent.setGreeting();
  }
}

The ngAfterViewInit the hook is perfect for accessing SeeChild variables because they are guaranteed to be defined at that time. They may or may not be put in ngOnInit.

public setGreeting() {
  this.name = 
    (this.whoAreYouRef.nativeElement as HTMLInputElement).value;
  this.greeting = 'Hello ' + (this.name ? this.name : 'stranger') + '!';
}

Assuming the setGreeting () The method is coded to revert to a default name, as above, the user would be greeted with “Hello stranger!” when loading the application for the first time:

Show child in JavaScript

How to Access the Home Directive Using ViewChild

Directives are a special type of class that allow you to modify the appearance or behavior of DOM elements and Angular components. In our case, we could offload all the host functionality to an attribute directive like this:

{{greeting}}p>

The host variable is still there, but it is now defined by the Reception directive, the full code of which can be seen below:

import { Directive, ElementRef, Input, OnChanges, Renderer2, SimpleChanges } from '@angular/core';

@Directive({
  selector: '[greet]'
})

export class GreetDirective implements OnChanges {
  @Input('greet') 
  private name;

  constructor(
    private elem: ElementRef, 
    private renderer: Renderer2
  ) { }

  ngOnChanges(changes: SimpleChanges): void {
    this.renderer.setProperty(
      this.elem.nativeElement,
      'innerText',
      'Hello ' + (this.name ? this.name : 'stranger') + '!'
    );
  }
}

It implements the OnChanges hook so that it can listen for updates to the name Input variable. Whenever its value changes, the directive uses the Renderer2 class to define its host element – the paragraph element – internal text property to the greeting.

Just like components, if you only have one instance of a directive in a component, you can refer to it by class name without needing a model reference selector. Here is an interesting use of a stand-alone setter that is not associated with a class variable. Instead, it sets the welcome message for the child directive:

@ViewChild(GreetDirective)
set greeting(directive: GreetDirective) {
  directive.greeting = 'Buongiorno';
};

The directive, in turn, has the standard combination of private member variable and public setter:

private _greeting = 'Hello';

public set greeting(greeting: string) {
  this._greeting = greeting;
}

Rather than returning the greeting to the parent component, it continues and updates the greeting.

item directly using Renderer2 setProperty () method. It accepts an element, a property, and a property value:

this.renderer.setProperty(
  this.elem.nativeElement,
  'innerText',
  'Hello ' + (this.name ? this.name : 'stranger') + '!'
);

You can find the demo of this tutorial on stackblitz.com.

Conclusion

This tutorial covered the SeeChild the many features of the decorator as well as the different ways of using it. As we’ve seen, we can use it to reference components, DOM elements, and directives and store them as a variety of types.

Read: Filter DOM nodes using a TreeWalker.


Source link

Share.

About Author

Leave A Reply