I have noticed if we declare a [ngClass] depending on a function, the app is calling the function continuously. Or if we bind to a boolean variable it is checking the value also if nothing happens.
I wanted to know if there is a way to have same effect of ngClass but calling the function or checking the boolean value only when "something happens". When press a button, or press any button.
I don't know if the solution could be using ngChange but I dont see the way to change the class then without refer to DOM elements in the controller directly what I am trying to evade.
Using :host(..) and @HostBinding
Consider you have a component which you’d like have different CSS classes applied based on some setting, like .yellow-style in case when you specify and .red-style when you pass in red: .
What’s important to note here is that, different to what we did so far, we don’t want the CSS class to be applied on some element that’s internal to our component, but onto the component itself. Example:
<styled style="red" _nghost-c0="" ng-reflect-style="red" class="red-
style">
<div _ngcontent-c0="">
I'm a div that wants to be styled
</div>
</styled>
Still, for reusability purposes, our styles should be supplied with the component itself, so again we use the styles property of our StyledComponent:
@Component({
selector: 'styled',
template: `
<div>
I'm a div that wants to be styled
</div>
`,
styles: [
`
:host(.yellow-style) {
background-color: yellow;
border: 1px solid black;
display:block;
}
:host(.red-style) {
background-color: red;
border: 1px solid black;
color: white;
display:block;
}
`
]
})
export class StyledComponent { }
As you can see, we use the special :host(...) selector to target the styles on the element that hosts the component. More info on the official docs about this. In this way .yellow-style as well as .red-style will be visible at the host component level while they’d be otherwise encapsulated and only applicable to elements within our StyledComponent.
Next, we define an @Input() property which allows us pass in the style configuration.
@Component({...})
export class StyledComponent {
@Input() style;
}
What we’re still missing is to programmatically set the CSS class on our host element based on the value of the style input property. We use the @HostBinding for this:
import { Component, Input, HostBinding } from '@angular/core';
@Component({ ... })
export class StyledComponent {
@Input() style;
@HostBinding('class.yellow-style') yellowStyle:boolean = false;
@HostBinding('class.red-style') redStyle:boolean = false;
ngOnChanges(changes) {
let newStyle = changes.style.currentValue;
if(newStyle === 'yellow') {
this.yellowStyle = true;
this.redStyle = false;
} else if(newStyle === 'red') {
this.yellowStyle = false;
this.redStyle = true;
} else {
// nothing here.. (fallback?)
}
}
}
In the ngOnChanges we the style input property changes, we properly adjust our style flags. (Note this is by far not the most intelligent code, but it’s simple enough so you get the idea :wink:).
TEXT FROM: https://juristr.com/blog/2016/01/learning-ng2-dynamic-styles/ ALL MERITS THERE. COLLECTED TO SPREAD. ALSO YOU HAVE AN EXAMPLE TO PLAY IN THE WEBSITE.