У меня есть DOM, который выглядит примерно так:
<app>
<router-outlet></router-outlet>
<project>...</project>
</app>
где project
элемент вставлен маршрутизатором.
Как добавить класс к этому элементу?
У меня есть DOM, который выглядит примерно так:
<app>
<router-outlet></router-outlet>
<project>...</project>
</app>
где project
элемент вставлен маршрутизатором.
Как добавить класс к этому элементу?
Предполагая, что вы всегда хотите, чтобы класс применялся к этому компоненту, вы можете использовать host
в своих метаданных компонента:
@Component({
selector:'project',
host: {
class:'classYouWantApplied`
}
})
Результат:
<app>
<router-outlet></router-outlet>
<project class="classYouWantApplied">...</project>
</app>
Ключом является /deep/ ключевое слово:
:host /deep/ router-outlet + project {
display: block;
border: 10px solid black;
}
Это работает без каких-либо дополнительных настроек.
:host /deep/ router-outlet + *
для любого компонента, динамически создаваемого Angular Router.
Поскольку Angular 4.3.0 сделал /deep/
устаревшим, его предлагаемая альтернатива - ::ng-deep
. И было долгое обсуждение об этом.
используйте подстановочный знак adjacent sibling selector
и *
, чтобы выбрать элемент, следующий сразу за router-outlet
styles.css
router-outlet + * {
/* your css */
}
Вы можете использовать соседний селектор sibling
router-outlet + project { ... }
https://developer.mozilla.org/en/docs/Web/CSS/Adjacent_sibling_selectors
но только если подход @drewmoore не применяется.
Вы можете сделать это с помощью HostBinding
, который фактически совпадает с использованием ранее указанного свойства host
, хотя этот метод выдает ошибку TSLint с правилами листинга по умолчанию.
В вашем компоненте, на котором вы хотите применить класс:
import { Component, HostBinding, Host (optional for typing) } from '@angular/core';
@Component({...})
export class GiveMeAClassComponent {
@HostBinding('class.some-class') someClass: Host = true;
...
}
И затем в корневом файле styles.scss
вы можете добавить следующее:
.some-class {
// Styles in here will now be applied to your GiveMeAClassComponent at a root level
}
Если вам нужно добавить класс условно, вы можете добавить его программно из компонента:
constructor(private renderer: Renderer2, private elemRef: ElementRef) {
if(someCondition){
renderer.addClass(elemRef.nativeElement, 'myClass');
}
}
<app>
<div class="your css class">
<router-outlet></router-outlet>
</div>
</app>
Это работает для меня
В настоящее время Angular 6 рекомендует мне использовать @HostBindings и @HostListeners вместо свойства host:
export class ProjectComponent {
@HostBinding('class') classes = 'classYouWantApplied';
}
Я создал RouterOutletHelperDirective
, который можно изменять по мере необходимости.
Ваш вариант использования может отличаться, но для меня:
ActivatedRoute
.Вы используете это так (класс необязательный):
<router-outlet routerOutletHelper
[routerOutletHelperClass]="'blue-border'"></router-outlet>
Затем создайте директиву, добавьте и экспортируйте ее в модуль приложения.
import { Directive, ElementRef, Renderer2, Input } from "@angular/core";
import { RouterOutlet } from "@angular/router";
import { Subscription } from "rxjs";
@Directive({
selector: 'router-outlet[routerOutletHelper]'
})
export class RouterOutletHelperDirective
{
constructor(private routerOutlet: RouterOutlet,
private element: ElementRef<HTMLElement>,
private renderer: Renderer2) { }
subscription = new Subscription();
@Input('routerOutletHelperClass')
customClassName: string | undefined;
ngOnInit()
{
this.subscription.add(this.routerOutlet.activateEvents.subscribe((_evt: any) => {
// find the component element that was just added
const componentElement = this.element.nativeElement.nextSibling;
// add a custom class
if (this.customClassName)
{
this.renderer.addClass(componentElement, this.customClassName);
}
// add my default classes, unless the activated route data
// (specified in module routing file) has { addDefaultClasses: false }
if (this.routerOutlet.activatedRouteData && this.routerOutlet.activatedRouteData.addDefaultClasses !== false)
{
// these are my application default classes (material / theming)
// (an additional data parameter could be 'darkTheme: boolean')
this.renderer.addClass(componentElement, 'mat-typography');
this.renderer.addClass(componentElement, 'rr-theme-light');
}
}));
}
ngOnDestroy()
{
this.subscription.unsubscribe();
}
}
так как маршрутизатор внедряет компонент после элемента router-outler, если мы хотим стилизовать все внедренные компоненты с одним и тем же набором правил, может оказаться полезным следующее правило.
оператор css "+" выбирает первый элемент одного типа, в то время как звездочка (*) используется в качестве символа подстановки для выбора любого первого элемента-роутера
router-outlet + * {
// your rules
}