Reputation: 24993
What's the proper way of accessing native element in angular2 (2 diff ways) so I have seen code that uses:
constructor(ele: ElementRef) {
let myEl = ele.nativeElement;
// do some work on myEl such as jQuery(myEl).hide()
...
As well as code that uses native dom via BrowserDomAdapter:
constructor(viewContainer:ViewContainerRef) {
let dom = new BrowserDomAdapter();
let el = viewContainer.element.nativeElement;
let myEle = dom.getElementsByClassName(el, element)[0];
// or jQuery(myEle).hide()
...
I am wondering what's the Pro / Cons and "proper" way of doing things. Unfortunately, the docs seem scarce still.
I am assuming the latter will give you WebWorkers support through the interface, but it is just my assumption.
Upvotes: 18
Views: 39366
Reputation: 1
There is a (probably intentionally) undocumented feature for that. You don't have to deal with views and with injected inputelements.
Furthermore, simply giving a
constructor(private e: ElementRef)
also won't work, it will be compilable by the typescript, but it will give you a parameter error in the runtime initializaton.
Finally I could find a solution in only 3 hours of digging:
import { Component, Directive, ElementRef, Inject } from "@angular/core";
@Component({
selector: "my-selector",
template: "my-template"
})
export class MyComponent {
private domNode: HTMLElement = null;
constructor( @Inject(ElementRef) elementRef: ElementRef) {
this.domNode = elementRef.nativeElement;
}
}
As you can see, the constructor will get the ElementRef
if and only if you have injected the parameter with an @Inject(ElementRef)
keyword. Both Inject
and ElementRef
should be imported from the angular core.
ElementRef.nativeElement
is the HTML DOM node what you are looking for. You have the chance to catch it only in the constructor, so don't miss the opportunity.
In the Angular documentation, they try to convince you that you don't need it, in their dialect it means that they admit that you need it, but they don't want you to use it.
In earlier angular versions it worked even without the @Inject
thing, but fortunately the Angular development always Provides
us newer and newer secrets in their otherways "stable" product.
Extension:
There was a comment (currently moved into a chatroom), it said that the @Inject annotation is not needed if you have emitDecoratorMetadata: true
in your tsconfig.json
. My experiences contradict this, furthermore it breaks the wall between the js and ts, but it is also a possible solution. It is possible, that the experiences of the commenter are from a previous week.
Upvotes: 4
Reputation: 658253
<div #foo>
@ViewChild() foo;
ngAfterViewInit(){
foo.nativeElement...
}
or if transcluded
@ContentChild() foo;
ngAfterContentInit(){
foo.nativeElement...
}
Allow to pick elements by template variable or component or directive type. (with a type you'll get the component instance instead of the element though.
or
constructor(@ViewChildren('foo') elements) {...
constructor(@ContentChildren('foo') elements) {...
@ViewChild
provides a live view to matching elements with changes subscription.
See also
Upvotes: 25