micah
micah

Reputation: 8096

Reference Specific Element in an Angular 2 Component?

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

Answers (1)

JayChase
JayChase

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

Related Questions