¿Cómo agregar "clase" al elemento anfitrión?

Resuelto lascarayf asked hace 8 años • 11 respuestas

No sé cómo agregar a mi componente un atributo de clase<component></component> dinámica pero dentro de la plantilla html (component.html).

La única solución que encontré es modificar el elemento mediante el elemento nativo "ElementRef". Esa solución parece un poco complicada para hacer algo que debería ser muy sencillo.

Otro problema es que CSS debe definirse fuera del alcance del componente, rompiendo la encapsulación del componente.

¿Existe una solución más sencilla? Algo así como <root [class]="..."> .... </ root>dentro de la plantilla.

lascarayf avatar Jan 07 '16 02:01 lascarayf
Aceptado

De esta manera no es necesario agregar CSS fuera del componente:

@Component({
   selector: 'body',
   template: 'app-element',
   // prefer decorators (see below)
   // host:     {'[class.someClass]':'someField'}
})
export class App implements OnInit {
  constructor(private cdRef:ChangeDetectorRef) {}
  
  someField: boolean = false;
  // alternatively also the host parameter in the @Component()` decorator can be used
  @HostBinding('class.someClass') someField: boolean = false;

  ngOnInit() {
    this.someField = true; // set class `someClass` on `<body>`
    //this.cdRef.detectChanges(); 
  }
}

Ejemplo de plomero

Este CSS se define dentro del componente y el selector solo se aplica si la clase someClassse establece en el elemento host (desde afuera):

:host(.someClass) {
  background-color: red;
}
Günter Zöchbauer avatar Jan 06 '2016 21:01 Günter Zöchbauer

La respuesta de Günter es excelente (la pregunta es sobre el atributo de clase dinámica ), pero pensé en agregar solo para completar...

Si está buscando una forma rápida y limpia de agregar una o más clases estáticas al elemento host de su componente (es decir, para fines de diseño de temas), simplemente puede hacer:

@Component({
   selector: 'my-component',
   template: 'app-element',
   host: {'class': 'someClass1'}
})
export class App implements OnInit {
...
}

Y si usa una clase en la etiqueta de entrada, Angular fusionará las clases, es decir,

<my-component class="someClass2">
  I have both someClass1 & someClass2 applied to me
</my-component>
JoshuaDavid avatar Jan 08 '2017 01:01 JoshuaDavid

Simplemente puede agregar @HostBinding('class') class = 'someClass';dentro de su clase @Component .

Ejemplo:

@Component({
   selector: 'body',
   template: 'app-element'       
})
export class App implements OnInit {

  @HostBinding('class') class = 'someClass';

  constructor() {}      

  ngOnInit() {}
}
Mike D3ViD Tyson avatar Oct 25 '2019 10:10 Mike D3ViD Tyson

Si desea agregar una clase dinámica a su elemento host, puede combinarla HostBindingcon un captador como

@HostBinding('class') get class() {
    return aComponentVariable
}

Demostración de Stackblitz en https://stackblitz.com/edit/angular-dynamic-hostbinding

Saksham avatar Jan 13 '2020 07:01 Saksham

Solución CSS PURA NONE-VERBOSE (HOSTBINDING)


Otro problema es que CSS debe definirse fuera del alcance del componente, rompiendo la encapsulación del componente.

Esto no es verdad. Con scss (SASS) puedes diseñar fácilmente el componente (en sí mismo; host) de la siguiente manera:

:host {
    display: block;
    position: absolute;
    width: 100%;
    height: 100%;
    pointer-events: none;
    visibility: hidden;

    &.someClass {
        visibility: visible;
    }
}

De esta manera la encapsulación queda "inteligible".

Youp Bernoulli avatar Sep 29 '2020 10:09 Youp Bernoulli