I have Angular 6.0.0 application. Need to dynamically append classes to html elements. Ideally, this should be implemented via directive. Currently I have something like this and it works OK.
<div class="class1 prefix-{{variable}}"></div>
I want to make the prefix reusable and I am trying to reach the better result by using a directive:
html:
<div class="class1" [appendBusinessLogicClass]="variable"></div>
appendBusinessLogicClass.directive.ts:
export class AppendBusinessLogicClass {
readonly prefix = 'prefix';
@HostBinding('class') class = ''; // this clears the html class1
@Input('appendBusinessLogicClass') set appendBusinessLogicClass(variable: string) {
this.class = this.prefix + '-' + variable;
}
}
But the HostBinding CLEARS class1
in the html code. But I'd like to APPEND 'prefix-rand'
to the class list.
Note, that we do not know variable
at the compile time.
Thanks
What you're actually doing now is binding to the class attribute, so basically the value will be set
to this.class
, which is completely fine. However, it turns out you're not actually getting the initial value from the 'class' attribute and this means no matter whatever you set class
to be on your template, the value will always be overwritten. So basically Angular is taking over setting that class
attribute.
So, what you have to do is get a reference of that value in the class
attribute. In Angular you can actually consider any html
attribute to be an input to your component/directive, the only thing you have to do is annotate it with an @Input
decorator. Here we're saving the value of the class
attribute to defaultClassList
and then using it to compute the new class
attribute value, so your code could look like this:
export class AppendBusinessLogicClass {
readonly prefix = 'prefix';
@Input('class')
defaultClassList;// `class` is a keyword so we're calling it defaultClassList instead
@HostBinding('class')
classList;// `class` is a keyword so we're calling it classList instead
@Input('appendBusinessLogicClass') set appendBusinessLogicClass(variable: string) {
this.classList = this.defaultClassList + " " + this.prefix + '-' + variable;
}
}
So to sum up, you end up getting the attribute value defined in your template and including it in your bound this.classList
whenever the value you pass to the directive is set.