J'ai un DOM qui ressemble à quelque chose comme ça:
<app>
<router-outlet></router-outlet>
<project>...</project>
</app>
où project
élément est inséré par le routeur.
Comment ajouter une classe à cet élément?
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>
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.
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.
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.
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
}
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');
}
}
<app>
<div class="your css class">
<router-outlet></router-outlet>
</div>
</app>
Ça marche pour moi
Actuellement, Angular 6 me recommande d’utiliser @HostBindings et @HostListeners au lieu de la propriété Host:
export class ProjectComponent {
@HostBinding('class') classes = 'classYouWantApplied';
}
J'ai créé une RouterOutletHelperDirective
qui peut être modifiée si nécessaire.
Votre cas d'utilisation peut être différent mais pour moi:
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();
}
}