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
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"
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
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');
Solution based on @RandallTo 's answer above.
Angular
ngAfterViewInit() {
window.setTimeout(function () {
const arr: HTMLCollection = document.getElementsByClassName('disable-autocomplete');
for (let i = 0; i < arr.length; i++) {
arr[i].removeAttribute('readonly');
}
}, 500);
}
HTML
<input type="text" name="username" readonly="" class="form-control disable-autocomplete"/>
CSS
.disable-autocomplete {
background-color: #fff;
}
Adding the white background colour means that you won't get a flash as the form loads with readonly fields (which are grey by default) which then turn white when the readonly attribute is removed.
You don't need the if statement in my version because you only set readonly
and .disable-autocomplete
on the fields for which you want to disable autocomplete.
For example you might want to allow autocomplete on the email field but not in the username field.
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.
To remove a class, you still can use setElementClass
, the isBool
should be set to false
. See this link for more info https://github.com/angular/angular/blob/9de76ebfa545ad0a786c63f166b2b966b996e64c/modules/%40angular/platform-browser/src/dom/dom_renderer.ts#L237