Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you access the element HTML from within an Angular attribute directive?

Tags:

angular

The Angular docs provide an example for creating an attribute directive that changes the background color of an element:

https://angular.io/docs/ts/latest/guide/attribute-directives.html

<p myHighlight>Highlight me!</p> 
import { Directive, ElementRef } from '@angular/core';  @Directive({ selector: '[myHighlight]' })  export class HighlightDirective {     constructor(el: ElementRef) {         el.nativeElement.style.backgroundColor = 'yellow';     } } 

Can I also use el.nativeElement to get the content of the element (e.g. Highlight me!), modify this and update the element?

like image 458
Gareth Whittaker Avatar asked Jun 23 '16 22:06

Gareth Whittaker


People also ask

What are the attribute directive in Angular?

The attribute directive changes the appearance or behavior of a DOM element. These directives look like regular HTML attributes in templates. The ngModel directive which is used for two-way is an example of an attribute directive.

What is an Angular attribute?

Angular attribute directives are a number of built-in directives that we can add to our HTML elements that give them a dynamic behavior. In summary, an attribute directive changes the appearance or behavior of a DOM element.

What is directive HTML?

What are Directives? At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ( $compile ) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.

What is native element in HTML?

Angular ElementRef is a wrapper around a native DOM element (HTML element) object. It contains the property nativeElement , which holds the reference to the underlying DOM object. We can use it to manipulate the DOM. We use the ViewChild to get the ElementRef of an HTML element in the component class.


2 Answers

So actually, my comment that you should do a console.log(el.nativeElement) should have pointed you in the right direction, but I didn't expect the output to be just a string representing the DOM Element.

What you have to do to inspect it in the way it helps you with your problem, is to do a console.log(el) in your example, then you'll have access to the nativeElement object and will see a property called innerHTML.

Which will lead to the answer to your original question:

let myCurrentContent:string = el.nativeElement.innerHTML; // get the content of your element el.nativeElement.innerHTML = 'my new content'; // set content of your element 

Update for better approach:

Since it's the accepted answer and web workers are getting more important day to day (and it's considered best practice anyway) I want to add this suggestion by Mark Rajcok here.

The best way to manipulate DOM Elements programmatically is using the Renderer:

constructor(private _elemRef: ElementRef, private _renderer: Renderer) {      this._renderer.setElementProperty(this._elemRef.nativeElement, 'innerHTML', 'my new content'); } 

Edit

Since Renderer is deprecated now, use Renderer2 instead with setProperty


Update:

This question with its answer explained the console.log behavior.

Which means that console.dir(el.nativeElement) would be the more direct way of accessing the DOM Element as an "inspectable" Object in your console for this situation.


Hope this helped.

like image 56
malifa Avatar answered Sep 21 '22 14:09

malifa


I suggest using Render, as the ElementRef API doc suggests:

... take a look at Renderer which provides API that can safely be used even when direct access to native elements is not supported. Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker or Universal.

Always use the Renderer for it will make you code (or library you right) be able to work when using Universal or WebWorkers.

import { Directive, ElementRef, HostListener, Input, Renderer } from '@angular/core';  export class HighlightDirective {     constructor(el: ElementRef, renderer: Renderer) {         renderer.setElementProperty(el.nativeElement, 'innerHTML', 'some new value');     } } 

It doesn't look like Render has a getElementProperty() method though, so I guess we still need to use NativeElement for that part. Or (better) pass the content in as an input property to the directive.

like image 27
Mark Rajcok Avatar answered Sep 20 '22 14:09

Mark Rajcok