Динамически добавлять классы для размещения элементов с помощью @HostBinding в Angular?

Вопрос:

Можно ли использовать @HostBinding таким образом добавлять, удалять или переключать классы на элементе хоста и не удалять ранее существующие классы, в частности, когда классы должны динамически переключаться?

Например, это добавит light класс и быть не разрушительным для предыдущих классов, однако, light не может быть динамичным.

Представьте себе этот визуализированный dom-узел:

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

С этим контроллером:

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

}

Где, как этот пример контроллера, динамически добавит класс light, но, насколько мне известно, удалит другие классы на элементе host.

@HostBinding('class') theme;

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

В конце второй пример переопределяет элемент dom, чтобы он выглядел так:

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

И, следовательно, удалить предыдущие классы, что не желательно. Любые идеи о том, как получить лучшее из обоих миров?

2 ответа

Изменить эту строку

@HostBinding('class') theme;

в

@HostBinding('class') 
get themeClass(){
  return this.theme;
};

обновленный

Вот версия, использующая ElementRef.
Реф Плункер

import {Component, Directive, NgModule, VERSION, ElementRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'


@Directive({selector: '[theme]'})
export class ThemeDirective {

  theme = 'dark';

  constructor(private elRef: ElementRef) {
  }

  ngOnInit() {
    this.elRef.nativeElement.classList.add(this.theme)
    setTimeout(() => this.changeTheme('light'), 2000)
  }

  changeTheme(newTheme) {
    this.elRef.nativeElement.classList.remove(this.theme)
    this.theme = newTheme  // or fetch from service
    this.elRef.nativeElement.classList.add(this.theme)
  }

}


@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2 class="someclass" theme>Hello {{name}}</h2>
      <div>Red in 2 seconds</div>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, ThemeDirective ],
//  directives: [ThemeDirective],
  bootstrap: [ App ]
})
export class AppModule {} 

Что вам нужно, так это [ngClass]:

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

Когда условие выполнено, "легкий" класс будет добавлен к someClasses1 someClasses2 и наоборот

Вы даже можете составить несколько классов с несколькими ситуациями, например:

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

Вы можете добавить столько условных классов, сколько вам нужно.

Другие вопросы по тегам