如何在路由器插座创建组件元素时将css类应用于组件元素?

问题描述 投票:27回答:9

我有看起来像这样的DOM:

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

其中project元素由路由器插入。

如何向此元素添加类?

angular angular2-routing
9个回答
39
投票

假设您始终希望将该类应用于此组件,则可以在组件元数据中使用host

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

导致:

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

0
投票

由于路由器在router-outlet元素之后注入组件,如果我们想要使用相同的规则集对所有注入的组件进行样式化,则以下规则可能会有所帮助。

css“+”运算符选择某种类型的第一个兄弟元素,而星号(*)用作通配符来选择路由器插座的任何第一个兄弟

router-outlet + * {
  // your rules
}

7
投票

关键是/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。关于这一点,有一个long discussion


7
投票

使用adjacent sibling selector*通配符选择紧跟router-outlet之后的元素

styles.css的

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

enter image description here


4
投票

您可以使用相邻的兄弟选择器

router-outlet + project { ... }

https://developer.mozilla.org/en/docs/Web/CSS/Adjacent_sibling_selectors

但只有@ drewmoore的方法不适用。


4
投票

您可以使用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
}

1
投票

如果需要有条件地添加类,可以从组件以编程方式添加它:

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

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

这适合我


1
投票

目前,Angular 6建议我使用@HostBindings和@HostListeners而不是host属性:

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

0
投票

我创建了一个RouterOutletHelperDirective,可以根据需要进行修改。

您的用例可能与我不同,但对我来说:

  • 我需要在每个路由器插座生成的项目上设置一组默认类
  • 我需要根据某些条件阻止此默认值,例如ActivatedRoute数据。

你这样使用它(该类是可选的):

<router-outlet routerOutletHelper
               [routerOutletHelperClass]="'blue-border'"></router-outlet>

然后创建指令,将其添加并导出到您的app模块。

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's 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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.