I'm trying to call functions on an element declared in my Angular 2 component.
The issue is that I don't know how to retrieve the element from my JS code.
If I can pass the element from the template to the JS code, it works, but
using document.querySelector
does not return anything.
Example code (plunk):
@View({
template: `
<div>
<span id="p1">{{name}}</span>
<span #p2>{{name}}</span>
</div>
`,
encapsulation: ViewEncapsulation.Native
})
export class Person {
sayHello(e) {
p1 = document.querySelector('p1');
console.log('p1:', p1)
p2 = document.querySelector('p2');
console.log('p2:', p2)
alert('VanillaId: ' + (p1 ? p1.innerHTML : 'null') +
'\nAngularId: ' + (p2 ? p2.innerHTML : 'null'));
}
}
I suspect that it has something to do with shadow dom, but I don't know how to
get the shadow root and use it to do the query. this
doesn't seem to expose
anything useful to access the dom.
Use ElementRef see it here http://plnkr.co/edit/LISYnq?p=preview
I did play around with your plunker:
I don't know how to retrieve the element from my JS code
It strikes me you might be able to just setup your component state in your js code and then mutate/display it usingg property binding, and communicate in/out with events.
If you provide a more specific use case maybe we can offer more advice. Anyway, heres the code:
person.ts
//a simple person component
import {Component, View, ViewEncapsulation, Input, ElementRef} from 'angular2/angular2'
@Component({
selector: 'my-person',
inputs: ['name'],
template: `
<pre>
<span> (Unsuspecting shadow dom node minding its own business)</span>
<span #p0el> Name : {{name}}</span>
<span #p1el> Passed in : {{p1}}</span>
</pre>
`,
encapsulation: ViewEncapsulation.Native
})
export class Person {
public p1:string = "...";
@Input('name') name:string;
constructor (elementRef: ElementRef) {
this.elementRef = elementRef;
}
sayHello(str) {
this.p1 = str;
this.elementRef.nativeElement.shadowRoot.querySelector('span').textContent = "BAM!"
}
}
app.ts
//our root app component
import {Component, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2'
import {Person} from './person'
@Component({
selector: 'my-app',
template: `
<div>
<!-- Passing the element here works fine -->
<button (click)="person.sayHello('Clicked!') && person.name = 'Clicky name'">Test</button>
<my-person #person [name]="'World'"></my-person>
</div>`,
directives: [CORE_DIRECTIVES, Person],
encapsulation: ViewEncapsulation.Native
})
export class App {
test(personComponent: Person) {
}
}