17

What is the difference between Renderer and ElementRef? In Angular both are used for DOM Manipulation. I am currently using ElementRef alone for writing Angular 2 directives. If I get more info about Renderer, I can use that in my future directives.

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Niyaz
  • 2,677
  • 3
  • 21
  • 40

2 Answers2

40

The Renderer is a class that is a partial abstraction over the DOM. Using the Renderer for manipulating the DOM doesn't break server-side rendering or Web Workers (where direct access to the DOM would break).

ElementRef is a class that can hold a reference to a DOM element. This is again an abstraction to not break in environments where the browsers DOM isn't actually available.

If ElementRef is injected to a component, the injected instance is a reference to the host element of the current component.

There are other ways to acquire an ElementRef instance like @ViewChild(), @ViewChildren(), @ContentChild(), @ContentChildren(). In this case ElementRef is a reference to the matching element(s) in the template or children.

Renderer and ElementRef are not "either this or that", but instead they have to be used together to get full platform abstraction.

Renderer acts on the DOM and ElementRef is a reference to an element in the DOM the Renderer acts on.

Shai Reznik - HiRez.io
  • 8,748
  • 2
  • 33
  • 33
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    I'm wondering why renderer methods require `elementRef.nativeElement` instead of working with `elementRef` like `viewContainerRef`. This seems to be a bit inconsistent. Any ideas? – Max Koretskyi Mar 03 '17 at 09:37
  • It looks inconsistent, but I think it isn't. In earlier beta versions `renderer` just took `ElementRef` but they changed it later. I think in platforms like `Universal` `ElementRef.nativeElement` doesn't actually refer to a DOM element. If you check https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html you'll see that `nativeElement` is of type `any` instead of `HTMLElement` – Günter Zöchbauer Mar 03 '17 at 09:41
  • _In earlier beta versions renderer just took ElementRef but they changed it later._ - that's interesting, thanks. yeah, `nativeElement` can refer to platform specific elements, but passing elementRef instead of elementRef.nativeElement is still a higher abstraction and would work any way – Max Koretskyi Mar 03 '17 at 09:47
  • I don't remember seeing a reason mentioned why they changed it. – Günter Zöchbauer Mar 03 '17 at 09:48
  • 2
    Just checked sources, existing renderer is depracated in the most recent versions. – Max Koretskyi Mar 03 '17 at 12:12
  • I think I saw something like that mentioned. I don't know yet what the alternative approach will be. – Günter Zöchbauer Mar 03 '17 at 12:25
6

Do notice that you should refrain from using ElementHref as it flagged with a security risk.

Angular 2 Documentation:

"Permitting direct access to the DOM can make your application more vulnerable to XSS attacks. Carefully review any use of ElementRef in your code. For more detail, see the Security Guide."

"Use this API as the last resort when direct access to DOM is needed. Use templating and data-binding provided by Angular instead. Alternatively you take a look at Renderer which provides API that can safely be used even when direct access to native elements is not supported."

Omri L
  • 739
  • 4
  • 12
  • 11
    Actually using `ElementRef` itself doesn't do any harm. The culprit is `ElementRef.nativeElement`. This is IMHO (I'm all but a security expert) only security relevant if user provided data is used to add to the DOM, right? – Günter Zöchbauer Sep 30 '16 at 07:20