Either i am using Angular Renerer2 wrong, or it is broken. Can anyone figure this out?
Asked Answered
R

2

7

Using plain old javascript, this is so simple:

myElement.style.setProperty('property', 'value', 'important');

In Angular, not so much. I have done an exhaustive search absolutely everywhere and can not find one single example for how to do this, so i am asking the question here.

Either Renderer2 in Angular is broken or i am just doing this wrong.

i import the following into my component:

import {ElementRef, Renderer2, RendererStyleFlags2 } from '@angular/core';

and, in my constructor:

constructor(private elRef: ElementRef,
            private renderer: Renderer2);

i set a style on an element in my template that works without issue:

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff');

when i try to set the important flag like this:

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', RendererStyleFlags2.Important);

or like this:

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', flags:RendererStyleFlags2.Important);

or like this:

public myFlags:RendererStyleFlags2;
this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', myFlags.Important);

or in another way like this:

public myFlags:RendererStyleFlags2.Important;
public myFlags:RendererStyleFlags2.Important = 1;

along with many other attempts using arrays and objects:

myFlags:any = {important: 1}

None of the above works.

This is the method as it exists in angular core:

setStyle(el: any, style: string, value: any, flags: RendererStyleFlags2): void {
    if (flags & RendererStyleFlags2.DashCase) {
      el.style.setProperty(
          style, value, !!(flags & RendererStyleFlags2.Important) ? 'important' : '');
    } else {
      el.style[style] = value;
    }
  }

Can anyone tell me what i am doing wrong here?

Rowlock answered 13/4, 2018 at 18:0 Comment(1)
Did you try to set both flags? RendererStyleFlags2.DashCase and RendererStyleFlags2.ImportantDemisemiquaver
D
8

It feels like you either need to use both of the renderer flags or add !important to the string value instead.

const flags = RendererStyleFlags2.DashCase | RendererStyleFlags2.Important;
this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff', flags);

Or

this.renderer.setStyle(this.elRef.nativeElement.querySelector('.my-div'), 'color', '#fff!important');
Demisemiquaver answered 13/4, 2018 at 18:26 Comment(4)
WOW, OK so your first suggestion, setting both flags works, but can you help me understand what setting the DashCase does exactly? I did not see any other change in the DOM outside of the inclusion of the !important flag.Rowlock
Look at the code you posted from Angular core. It is checking for the RendererStyleFlags2.DashCase first to see which code path to go down.Demisemiquaver
My best guess is that if you want to change the borderRadius property in CSS, you can specify it as borderRadius or border-radius. The way you are setting the CSS in JS dictates which way you have to specify the property.Demisemiquaver
worst documentation, only shallow things are covered. If anything little bit complex we have to jump through API docs which don't have any clue on why a thing is there. You saved me after 2 hours of frustration. Thanks, Mr.Strimpel.Funiculus
R
2

Another solution could be to overwrite the style attribute with the renderer, for example like this:

this.renderer.setAttribute(myElementHere, 'style', 'color: #FFF !important');

But warning, it will remove / overwrite already existing inline styles. For this case you could read the value of the current style attribute and append / prepend it to the value, which will be overwritten.

Note that this solution is a bit, I would say, hacky, but if you can deal with it, you're good to go.

I did no performance tests or something like that (setStyle vs setAttribute).

This is just to complete the possibilities of overwriting inline styles.

Reentry answered 16/8, 2019 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.