web-dev-qa-db-fra.com

Comment appliquer la classe css à un élément du composant créé par routeur-sortie?

J'ai un DOM qui ressemble à quelque chose comme ça:

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

project élément est inséré par le routeur.

Comment ajouter une classe à cet élément?

25
Kugel

En supposant que vous souhaitiez toujours appliquer la classe à ce composant, vous pouvez utiliser Host dans les métadonnées de votre composant: 

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

Résultant en: 

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

La clé est / deep / mot clé:

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

Cela fonctionne sans aucune configuration supplémentaire.

:Host /deep/ router-outlet + * pour tout composant créé dynamiquement par Angular Router.

Édité 2018/3/5:

Puisque (4.3.0.0 angulaire } _ rendait /deep/ obsolète, son alternative suggérée est ::ng-deep. Et il y a eu une longue discussion à ce sujet.

7
Val

Vous pouvez utiliser le sélecteur de fratrie adjacent

router-outlet + project { ... }

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

mais seulement si l'approche de @ drewmoore ne s'applique pas.

4
Günter Zöchbauer

utilisez les caractères génériques adjacent sibling selector et * pour sélectionner l'élément immédiatement après le router-outlet


styles.css 

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

 enter image description here

3
JED

Vous pouvez le faire avec une HostBinding, ce qui revient en fait à utiliser la propriété Host déjà mentionnée, bien que cette méthode génère une erreur TSLint avec des règles de liste par défaut.

Dans votre composant sur lequel vous souhaitez appliquer une classe:

import { Component, HostBinding, Host (optional for typing) } from '@angular/core';

@Component({...})
export class GiveMeAClassComponent {
    @HostBinding('class.some-class') someClass: Host = true;
    ...
}

Et ensuite, dans votre fichier racine styles.scss, vous pouvez ajouter ce qui suit:

.some-class {
    // Styles in here will now be applied to your GiveMeAClassComponent at a root level
}
3
lordchancellor

Si vous devez ajouter une classe de manière conditionnelle, vous pouvez l'ajouter par programme à partir du composant: 

constructor(private renderer: Renderer2, private elemRef: ElementRef) {
  if(someCondition){
    renderer.addClass(elemRef.nativeElement, 'myClass');
  }
}
1
adamdport
<app>
  <div class="your css class">
   <router-outlet></router-outlet>
</div>
</app>

Ça marche pour moi

1
Awinash jaiswal

Actuellement, Angular 6 me recommande d’utiliser @HostBindings et @HostListeners au lieu de la propriété Host:

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

J'ai créé une RouterOutletHelperDirective qui peut être modifiée si nécessaire.

Votre cas d'utilisation peut être différent mais pour moi:

  • J'avais besoin de définir un ensemble de classes par défaut sur chaque élément généré par routeur-prise
  • Je devais empêcher cette valeur par défaut en fonction de certaines conditions, telles que ActivatedRoute data.

Vous l'utilisez comme ceci (le cours est optionnel):

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

Créez ensuite la directive, ajoutez-la et exportez-la dans votre module d'application.

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();
    }
}
0
Simon_Weaver