Як додати "клас" до хост-елемента?


190

Я не знаю, як додати до свого компонента атрибут <component></component>динамічного класу, але всередині шаблону html (компонент.html).

Єдине знайдене нами рішення - змінити елемент за допомогою елемента "ElementRef". Це рішення здається трохи складним зробити щось, що повинно бути дуже простим.

Інша проблема полягає в тому, що CSS має бути визначений за межами області компонентів, порушуючи інкапсуляцію компонентів.

Чи є більш просте рішення? Щось на зразок <root [class]="..."> .... </ root>шаблону.

Відповіді:


296
@Component({
   selector: 'body',
   template: 'app-element',
   // prefer decorators (see below)
   // host:     {'[class.someClass]':'someField'}
})
export class App implements OnInit {
  constructor(private cdRef:ChangeDetectorRef) {}

  someField: boolean = false;
  // alternatively also the host parameter in the @Component()` decorator can be used
  @HostBinding('class.someClass') someField: boolean = false;

  ngOnInit() {
    this.someField = true; // set class `someClass` on `<body>`
    //this.cdRef.detectChanges(); 
  }
}

Приклад Плункер

Таким чином, вам не потрібно додавати CSS поза компонента. CSS, як

:host(.someClass) {
  background-color: red;
}

працює з внутрішньої сторони компонента, і селектор застосовується лише в тому випадку, якщо клас someClassвстановлений на хост-елементі.


Мені довелося замість цього робити someField = truein ngOnInit()-метод ngAfterViewInit(). Я не міг змусити його працювати інакше.
Іван

Тут зробили виделку, яка показує фактичну :hostчастину роботи. Де я можу дізнатися більше про параметр хоста в декораторі @Component () (синтаксис мені не очевидний, а документація @Component не дуже пояснює ) або дізнатися більше про бажаний HostBinding (він вказаний лише як інтерфейс на Сайт Angular2?)
Червоний горох

Я не знаю кращих документів, але це просто інший спосіб робити те, що можна зробити@Input() @Output() @HostBinding() @HostListener() @ViewChild(ren)() @ContentChild(ren)()
Günter Zöchbauer

1
використовуйте геттер з іншим ім'ям для прив'язки хоста, який повертає перевернуте значення@HostBinding('class.xxx') get xxxclass(){ return !this.someField;}
Günter Zöchbauer

1
@YochaiAkoka не впевнений, на що йдеться. Я не знаю цього правила. Мінусів зазвичай більше, тож якщо ви можете уникнути додавання додаткових елементів, то вам слід уникати цього.
Günter Zöchbauer

184

Відповідь Гюнтера чудова (питання задає атрибут динамічного класу), але я подумав, що додам лише для повноти ...

Якщо ви шукаєте швидкий і чистий спосіб додати один або кілька статичних класів до хост-елемента вашого компонента (тобто для цілей стилізації), ви можете просто зробити:

@Component({
   selector: 'my-component',
   template: 'app-element',
   host: {'class': 'someClass1'}
})
export class App implements OnInit {
...
}

І якщо ви використовуєте клас на тезі введення, Angular об'єднає класи, тобто

<my-component class="someClass2">
  I have both someClass1 & someClass2 applied to me
</my-component>

1
Любіть це за простоту. Однак у моєму випадку елемент хоста інкапсульований іншим атрибутом, давайте назвемо його, ngcontent_hostніж будь-який з атрибутів елементів у моєму шаблоні , let's call those ngcontent_template , so if I put a style in the styleUrls` мого компонента, вони не вплинуть на елемент хосту, оскільки вони не вплинуть ngcontent_host, вони може впливати лише на елементи шаблону; вони можуть впливати тільки ngcontent_template. Я помиляюся? Будь-які пропозиції щодо цього? Я здогадуюсь, я міг завжди повернутисьViewEncapsulation.None
Червоний горох

11
Інший спосіб , це просто пропустити змінну @HostBinding('class.someClass') true;. Ви навіть можете це зробити з будь-якого класу, на який поширюється ваш компонент.
adamdport

3
Щоб додати кілька класів, ви можете зробити хостинг: {'[class]': '"class1 class2"'}
jbojcic

4
Якщо ви використовуєте {}варіант host:: ви можете встановити use-host-property-decoratorпараметр falseу tslint.json. Інакше ви отримаєте попередження IDE @adamdport Цей метод більше не працює. Використання Angular 5.2.2 в нашому додатку.
Рууд Вуст

1
Це тільки я, або старий спосіб здається кращим за новий? Я впевнений, що у них були вагомі причини мігрувати, але я ...
розчавити

13

Ви можете просто додати @HostBinding('class') class = 'someClass';всередину свого класу @Component .

Приклад:

@Component({
   selector: 'body',
   template: 'app-element'       
})
export class App implements OnInit {

  @HostBinding('class') class = 'someClass';

  constructor() {}      

  ngOnInit() {}
}

1
Також може використовуватися директива className, і краще уникати використання classв якості імені змінної (оскільки ви можете посилатися на неї та змінити її пізніше). Приклад: @HostBinding('className') myTheme = 'theme-dark';.
CPHPython


0

Ось як я це зробив (кутовий 7):

У компоненті додайте вхід:

@Input() componentClass: string = '';

Потім у HTML-шаблон компонента додайте щось на зразок:

<div [ngClass]="componentClass">...</div>

І, нарешті, в шаблоні HTML, куди ви інстантуєте компонент:

<root componentClass="someclass someotherclass">...</root>

Відмова: Я досить новачок у Angular, тому мені, можливо, просто пощастить тут!


2
Трохи некро, але: це не додає класу CSS до елемента хосту - який є елементом для <root>тегу, а не що-небудь, що ви додаєте в шаблон елемента.
мільйоз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.