3

I am wondering how can I find element inside a component using Renderer?

In angular1 I would just go:

link = (scope, element, attributes) => {
            var outsideBox = element.find('.outside-box');
}

Which returns me a <div class="outside-box"></div>

Any pointers are more than welcome!

uksz
  • 18,239
  • 30
  • 94
  • 161

2 Answers2

13

I would use its selectRootElement method:

import {Component,Renderer} from 'angular2/core';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <div class="outside-box"></div>
      <div (click)="onClick()">Click</div>
    </div>
  `
})
export class AppComponent {
  constructor(private renderer:Renderer) {
  }

  onClick() {
    var outsideBox = this.renderer.selectRootElement('.outside-box');
  }
}

See this plunkr: https://plnkr.co/edit/9OJ9kr?p=preview

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • Funny thing - I was putting the same code as you did in constructor in my component - but it was not working. I had to put it in ngOnChanges -> it seems like constructor is fired before HTML is, is that correct? – uksz Mar 16 '16 at 13:35
  • 2
    Yes, I think that calling in the constructor is too early because the template is rendered later. `ngOnInit` would be a better place since `ngOnChanges` can be called several times. But you're right the first time it's called, it's before `ngOnInit`... – Thierry Templier Mar 16 '16 at 13:40
  • 1
    actually, i think ngOnChanges seems to be invoked before ngOnInit – uksz Mar 16 '16 at 14:00
  • Yes agreed! See my comment above. From angular.io docs: "ngOnInit - after the first ngOnChanges" ;-) – Thierry Templier Mar 16 '16 at 14:01
  • Does ngOnChange detects the value that has changed? – uksz Mar 16 '16 at 14:02
  • 1
    Yes, the bound value that has changed. So it can be called several times later... – Thierry Templier Mar 16 '16 at 14:04
  • 1
    `selectRootElement` removes child nodes from the element. I guess it is intended to prepare the element for component init. Certainly not what's required. – Estus Flask Oct 04 '16 at 04:47
  • I just tried this and it doesn't seem to work any more with Render2 in angular 4.... – davaus Sep 22 '17 at 02:15
3

I would use Plunker - BrowserDomAdapter

import {Component,ElementRef} from 'angular2/core';
import {BrowserDomAdapter} from 'angular2/platform/browser';
//import { DOM } from 'angular2/src/platform/dom/dom_adapter';
@Component({
    selector: 'my-app',
    template: `
    <style>
      .test{
        color:green;
        background:white;
      }
    </style>
    <button (click)="add()" class="btnClass">Add New Element</button>
    `
})

export class AppComponent {
 dom:BrowserDomAdapter;
  constructor(el:ElementRef) { 
    this.dom = new BrowserDomAdapter();
    console.log(el);
  }
  add(){

      console.log( this.dom.query(".btnClass"));    
      this.dom.addClass(this.dom.query(".btnClass"),"test");
      console.log(this.el);

  }
}

micronyks
  • 54,797
  • 15
  • 112
  • 146