7

Question:

Is it possible to use @HostBinding in such a way to add, remove, or toggle classes on a host element and not remove preexisting classes, in particular when the classes need to be dynamically toggled ?

For example, this will add light class and be non-disruptive to the previous classes;however, light cannot be dynamic.

Imagine this rendered dom node:

<div [classToggler] class="someClasses1 someClasses2' ></div>

With this controller:

@HostBinding('class.light') isLight = theme === 'light';  // true
ngOnInit() {
  this.store.select('classToggler').subscribe((className) => {
      this.theme = className || 'light'
  });

}

Where as this example controller, will add the light class dynamically but to my knowledge will remove other classes on host element.

@HostBinding('class') theme;

ngOnInit() {
  this.store.select('classToggler').subscribe((className) => {
      this.theme = className || 'light'
  });
}

In the end the second example will re-render the dom element to look like this:

<div [classToggler] class="light'></div>

And therefore, remove the previous classes, which isn't desired. Any ideas on how to get the best of both worlds?

Armeen Moon
  • 18,061
  • 35
  • 120
  • 233
  • Can you use a getter for `isLight` instead of assigning an expression? That might make it reactive in the same way as the second pattern. I'll see if I can mock up an example. – Richard Matsen Nov 29 '17 at 04:34
  • @RichardMatsen could you leave an answer the first answer isn't what I'm looking for? I want the ability to add (n) number of classes .light was just an example. – Armeen Moon Nov 29 '17 at 04:56
  • Will do. Still working on a Plunker (hate to post untested). – Richard Matsen Nov 29 '17 at 04:59

2 Answers2

5

Change this line

@HostBinding('class') theme;

to

@HostBinding('class') 
get themeClass(){
  return this.theme;
};
Sunil Singh
  • 11,001
  • 2
  • 27
  • 48
-3

What you need is [ngClass] like so :

<div [ngClass]="{'light':condition}" class="someClasses1 someClasses2" ></div>

When condition is true, "light" class will be added to someClasses1 someClasses2 and vice versa

You can even compose mulptiple classes with multiple situations like so :

<div [ngClass]="{'class1':condition1, 'class2':conditions2}" class="someClasses1 someClasses2" ></div>

you can add as many conditional classes as you need.

Mehdi
  • 2,263
  • 1
  • 18
  • 26
  • I think the OP is about a directive, so the solution has to be into the directive, not the html... – Random Sep 14 '18 at 06:47
  • The purpose of a directive is to be easily reusable. For instance I've landed here trying to apply multiple classes with a single directive (the person using the directive does not have to know which exact classes has to be applied in order to get the expected behavior). I also guess OP was making a more complex directive, which, among other actions, needs to apply a class... – Random Sep 17 '18 at 09:55
  • 1
    HostBinding means the OP needs the class on the host. – Sampgun Sep 25 '18 at 08:26