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


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.