Reputation: 8096
I have an element in an ng2 component that I want to manipulate directly. I don't need or want its properties to be handled by the framework because its properties will be updated on a second-by-second basis and I don't want it affecting the lifecycle. In my example (not the actual use case) I will use a timer that increments per second.
HTML-
<div class="timer"></div>
<div>Elapsed</div>
Component-
@Component({
selector: 'timer',
templateUrl: 'timer.html',
})
export class TimerComponent {
private time = 0;
// How do I get .timer ?
constructor(private $element: ElementRef) {}
onNgInit() {
setInterval(this.incrementTimer.bind(this), 1000);
}
private incrementTimer() {
this.time++;
this.$element.nativeElement.innerHTML = this.time;
}
}
I have a number of options to get the timer element, but I'm wondering if there is an easy way (an angular way) to label the element so that angular will understand/include it in the injector. I'd prefer not to search the DOM for this element, and I prefer not to tap the lifecycle every time I want to update.
Upvotes: 3
Views: 1747
Reputation: 11525
You can use ViewChild and a template reference variable to get the element in the component. For example set the template ref #timer on the timer div:
<div class="timer" #timer></div>
<div>Elapsed</div>
Then in the component you can get the timer and manipulate it using the Renderer (note that this is in AfterViewInit to make sure the element has been rendered):
import { Component, AfterViewInit, ViewChild, ElementRef, Renderer } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
@ViewChild('timer') timer: ElementRef;
constructor(private renderer: Renderer) { }
ngAfterViewInit() {
this.renderer.setElementProperty(this.timer.nativeElement, 'innerText', 'hello');
}
}
Upvotes: 5