Подтвердить что ты не робот

Как применить класс css к компоненту, когда он создается маршрутизатором?

У меня есть DOM, который выглядит примерно так:

<app>
    <router-outlet></router-outlet>
    <project>...</project>
</app>

где project элемент вставлен маршрутизатором.

Как добавить класс к этому элементу?

4b9b3361

Ответ 1

Предполагая, что вы всегда хотите, чтобы класс применялся к этому компоненту, вы можете использовать host в своих метаданных компонента:

@Component({
  selector:'project',
  host: {
      class:'classYouWantApplied`
  }
})

Результат:

<app>
    <router-outlet></router-outlet>
    <project class="classYouWantApplied">...</project>
</app>

Ответ 2

Ключом является /deep/ ключевое слово:

    :host /deep/ router-outlet + project {
        display: block;
        border: 10px solid black;
    }

Это работает без каких-либо дополнительных настроек.

:host /deep/ router-outlet + * для любого компонента, динамически создаваемого Angular Router.

Отредактировано 2018/3/5:

Поскольку Angular 4.3.0 сделал /deep/ устаревшим, его предлагаемая альтернатива - ::ng-deep. И было долгое обсуждение об этом.

Ответ 3

используйте подстановочный знак adjacent sibling selector и *, чтобы выбрать элемент, следующий сразу за router-outlet


styles.css

router-outlet + * {
  /* your css */
}

enter image description here

Ответ 5

Вы можете сделать это с помощью 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
}

Ответ 6

Если вам нужно добавить класс условно, вы можете добавить его программно из компонента:

constructor(private renderer: Renderer2, private elemRef: ElementRef) {
  if(someCondition){
    renderer.addClass(elemRef.nativeElement, 'myClass');
  }
}

Ответ 7

<app>
  <div class="your css class">
   <router-outlet></router-outlet>
</div>
</app>

Это работает для меня

Ответ 8

В настоящее время Angular 6 рекомендует мне использовать @HostBindings и @HostListeners вместо свойства host:

export class ProjectComponent {
  @HostBinding('class') classes = 'classYouWantApplied';
}

Ответ 9

Я создал 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();
    }
}

Ответ 10

так как маршрутизатор внедряет компонент после элемента router-outler, если мы хотим стилизовать все внедренные компоненты с одним и тем же набором правил, может оказаться полезным следующее правило.

оператор css "+" выбирает первый элемент одного типа, в то время как звездочка (*) используется в качестве символа подстановки для выбора любого первого элемента-роутера

router-outlet + * {
  // your rules
}