Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get reference of the component associated with ElementRef in Angular 2

Tags:

angular

I have this component in my template:

<vector-editor  #scaleControl                 [x]="scaleX"                 [y]="scaleY"                 [z]="scaleZ" >                </vector-editor> 

The vector-editor has the following structure:

export class VerticeControlComponent implements OnInit {     @Input() x: number;     @Input() y: number;     @Input() z: number;      ... } 

In my application I grab a reference to the #scaleControl using

@ViewChild('scaleControl') scaleControl: ElementRef; 

Now if I output scaleControl to the console I get this result:

enter image description here

As can be seen, the reference is not null and all the properties of my component are there. I want to access those properties, but in code the actual type of the scaleControl is ElementRef and not VectorEditorControl as seen in the output. Because of this, TypeScript doesn't me allow to use this.scaleControl.x.

I also tried to cast ElementRef like this

var temp = <VectorEditorControl>this.scaleControl 

but I get an error telling me that I cannot cast ElementRef to VectorEditorControl

In the end, I tried to access this.scaleControl.nativeElement but it's undefined...

What am I missing here?

like image 555
rbasniak Avatar asked Oct 07 '16 03:10

rbasniak


People also ask

How do I get ElementRef from components?

Getting ElementRef in Component ClassCreate a template reference variable for the element in the component/directive. Use the template variable to inject the element into component class using the ViewChild or ViewChildren.

How can I select an element in a component template?

To select an element in a component template with Angular, we can assign an ref to the element in the template. Then we can use ViewChild to access it. to assign the inputEl ref to the input element. in the template.

What is ElementRef nativeElement?

Angular ElementRef is a wrapper around a native element inside of a View. It's simply a class that wraps native DOM elements in the browser and allows you to work with the DOM by providing the nativeElement object which exposes all the methods and properties of the native elements.

Can we access DOM element inside Angular component constructor method?

You can get a handle to the DOM element via ElementRef by injecting it into your component's constructor: constructor(private myElement: ElementRef) { ... }


2 Answers

You should know the following things about using @ViewChild property decorator.

It uses the following Metadata Properties:

  • selector - the directive type or the name used for querying.
  • read - read a different token from the queried elements.

From source code:

export interface ViewChildDecorator {   /**    * You can use ViewChild to get the first element or the directive matching     * the selector from the    * view DOM. If the view DOM changes, and a new child matches the selector,    * the property will be updated.    *    * View queries are set before the `ngAfterViewInit` callback is called.    *    * **Metadata Properties**:    *    * * **selector** - the directive type or the name used for querying.    * * **read** - read a different token from the queried elements.    */   (selector: Type<any>|Function|string, {read}?: {read?: any}): any;   new (selector: Type<any>|Function|string, {read}?: {read?: any}): ViewChild; } 

If you don't provide the read parameter, @ViewChild() will return the:

  • component instance if there is.
  • ElementRef instance if there is no component applied
  • different token from the queried elements if you set read property

So if you want to get ElementRef from the child that is angular2 component (VerticeControlComponent) you need to explicitely tell using read: ElementRef:

@ViewChild('scaleControl', {read: ElementRef}) scaleControl: ElementRef; 

And then inside ngAfterViewInit hook or later you can write this.scaleControl.nativeElement to get DOM element.

Update

I wrote early:

  • different token from the queried elements if you set read property

Now I want to add what exactly we can read:

  • ElementRef

  • TemplateRef

  • ViewContainerRef

  • Provider

What does Provider mean here?

It means that if we defined any provider(in component or directive) on specific element then we can read it.

@Component({   selector: 'child',   template: `    <h2>I'm child</h2>   `,   providers: [     {       provide: 'test', useValue: 'x'     }   ] }) export class ChildComponent {  } 

So in consumer of this component we can write

@ViewChild(ChildComponent, { read: 'test' }) providerToken: string; 

to get value x.

Example

See also:

  • What are all the valid selectors for ViewChild and ContentChild?
like image 106
yurzui Avatar answered Sep 23 '22 18:09

yurzui


At the time of writing I recommend using the following method:

@ViewChild('scaleControl') scaleControl: ElementRef<VerticeControlComponent>; 

You can then have access to both the types.

  • ElementRef: using scaleControl
  • VerticeControlComponent: using scaleControl.nativeElement
like image 21
Sergio Carneiro Avatar answered Sep 23 '22 18:09

Sergio Carneiro