This article on ViewChild and ContentChild in Angular is part of the Learning Angular series.
Understanding View Encapsulation
Angular implements View Encapsulation by using a custom attribute to all the elements inside a particular component. This is known as Shadow DOM.
Shadow DOM is a new method being applied by browsers, btu it is not fully implemented by all browsers. So Angular emulates it by its own by adding a specific attribute to each of its component, making sure that everything that has been defined by the component is only used by the component, mainly css.
More on View Encapsulation
The encapsulation can be overridden by defining ‘encapsulation’ in the Component descriptor.
@Component({
…
encapsulation: ViewEncapsulation.None
// other options are also available - Native/Emulated
// Native uses the browser capability
// Emulated uses the Angular's Shadow DOM
})
69 – Using Local References in Templates
Local references can be made by adding the reference to the element by using a # followed by the reference name.
<input type="text" class="form-control" #serverNameElement>
This reference can be accessed anywhere inside the template, but not outside, not even the ts file.
Getting Access to the Template and DOM with @ViewChild
There is a way of getting access to any element:
Add the id in the element:
<input type="text" class="form-control" #serverContentInput>
And access it using the following in the ts file:
@ViewChild('serverContentInput') svrContentInput:ElementRef;
Rather than using ‘serverContentInput’, one can also use
@ViewChild(CockpitComponent) svrContentInput:ElementRef;
This will return the first instance of the particular element. This is generally not used as it is not very specific.
While one can also use the @ViewChild to set the value like:
this.svrContentInput.nativeElement.value = "Something";
one should not use this as it is very risky and the DOM should never be manipulated directly.
Projecting Content into Components with ng-content
Anything placed between our own component will get lost as Angular doesn’t care about it.
<app-cockpit> <h1>This is my own area</h1> </app-cockpit>
In the above case, the h1 tag gets lost and won’t be included in the rendering.
This can be avoided by using the ng-content directive in the cockpit.component.html file:
<ng-content><ng-content>
By using this, whatever is placed within the tag will get rendered at the position where tag is used in the component.
This will help in rendering different types of views based on requirements, depending on where the CustomComponent is used.