Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get/set/remove element attribute in Angular 2 using "the angular way"?

Tags:

angular

I've been reading some articles about Angular 2 pitfalls and what to avoid, one of those things revolves around not accessing the DOM directly.

I noticed that the Renderer is quite useful since it contains some methods that can help avoid the DOM pitfall. However, I noticed that it doesn't contain any get functions, only set functions such as setElementAttribute, setElementClass and so on.

So my question is rather simple, how do you use the above functions but as the get and remove version? Do they live in another class or how do you work with retrieving attributes or classes for example?

like image 934
Chrillewoodz Avatar asked Jun 18 '16 09:06

Chrillewoodz


5 Answers

To remove attributes from the DOM you provide a value of null.

To set an attribute (attribute value can be an empty string if you wish):

myrenderer.setElementAttribute(elementRef.nativeElement, 'attributename', 'attributevalue');

To remove an attribute:

myrenderer.setElementAttribute(elementRef.nativeElement, 'attributename', null);

To get an element attribute value, you have the nativeElement which you pass to setElementAttribute, so you can use that to get the attribute value using standard Javascript:

elementRef.nativeElement.getAttribute('attributename');
like image 78
David Avatar answered Oct 18 '22 07:10

David


Angular2 doesn't provide any support to get anything from the DOM except ElementRef and events.
The Angular2 way is to maintain the state in the model and update the DOM to reflect that state.

If you need to read from the DOM you can use direct DOM access or provide a custom Renderer that provides the features you're missing in the default Renderer.

Examples for custom renderers

  • Custom renderer for Angular2
  • https://github.com/ralfstx/angular2-renderer-example/blob/master/src/custom-renderer.ts
like image 33
Günter Zöchbauer Avatar answered Oct 18 '22 08:10

Günter Zöchbauer


In case someone is still looking for this (as I did), i shall add up a bit on David's answer which was on Angular's native renderer.

You have all this requested functionality in newest Angular Renderer2

Particularly if you want to completely remove attributes (ex. invalid aria tags in community components that fail accessibility tests) from elements and not set their value to null, there is

renderer2.removeAttribute(elementRef.nativeElement, 'AttributeName');

EDIT: You should use AfterViewInit() lifecycle, as described in other answers, as the initial view must be rendered before you make any custom DOM changes.

like image 4
Kostis Tr Avatar answered Oct 18 '22 06:10

Kostis Tr


I don't like accessing the dom in Angular but this use case you may need to. The only way to disable the annoying auto complete seems to be to add the attribute "readonly" and remove it after the form loads.

ngAfterViewInit() {
      window.setTimeout(function () {

         var arr: HTMLCollection = document.getElementsByClassName('form-control');
         for (var i = 0; i < arr.length; i++) {
           if (arr[i].hasAttribute("readonly")) {
             arr[i].removeAttribute('readonly');
           }
         }

   }, 500);
}
like image 3
RandallTo Avatar answered Oct 18 '22 07:10

RandallTo


Since getAttribute is just a method, you could use invokeElementMethod:

var attr = renderer.invokeElementMethod(elementRef.nativeElement, 'getAttribute', []);

This approach will not work if you switch to server-side rendering (except event callbacks like mouse click).

Extending DOMRenderer effectively means tight coupling to browser implementation, which is the same as direct nativeElement manipulation.


It seems that you should not invoke getters at all. So the question is why do you need to know attribute value or class name?

You could create specific directive or template variable and use it with ViewChild/ViewChildren, or create appropriate data model and bind with [class.name]="nameEnabled"

like image 2
kemsky Avatar answered Oct 18 '22 07:10

kemsky