Angular2 agrega clase a la etiqueta del cuerpo

97

¿Cómo puedo agregar una clase a la etiqueta del cuerpo sin hacer que el cuerpo sea ​​el selector de aplicaciones y usar el enlace de host?

Intenté usar el Renderer pero cambia todo el cuerpo

Clase de enlace angular 2.x en la etiqueta del cuerpo

Estoy trabajando en una gran aplicación angular2 y cambiar el selector de raíz afectará mucho código, tendré que cambiar mucho código

Mi caso de uso es este:

Cuando abro un componente modal (creado dinámicamente) quiero que la barra de desplazamiento del documento se oculte

Rachid O
fuente
1
En realidad, si trabaja con js dentro de la página html, ¿cuál es el problema con el uso document.body.className|classList?
yurzui
jaja si fuera así de simple :) pero es una mala práctica acceder a dom directamente
Rachid O
Se puede escribir un gran contenedor que se va a ejecutar varios segundos y al final añadido classa body. Si no va a utilizar la representación del servidor o el trabajador web, ¿a qué le tiene miedo?
yurzui
¿Entonces no hay mejor solución que esta?
Rachid O
4
No puedo entender a estas personas abusivas que votan negativamente y cierran preguntas sin una razón válida
Rachid O

Respuestas:

213

Me encantaría comentar. Pero debido a la falta de reputación, escribo una respuesta. Bueno, conozco dos posibilidades para solucionar este problema.

  1. Inyecte el documento global. Bueno, puede que no sea la mejor práctica, ya que no sé si nativescript, etc., lo admite. Pero al menos es mejor que usar JS puro.
constructor (@Inject (DOCUMENT) private document: Document) {}

ngOnInit () {
   this.document.body.classList.add ('prueba');
}

Bueno y quizás incluso mejor. Puede inyectar el renderizador o el renderizador 2 (en NG4) y agregar la clase con el renderizador.

export class myModalComponent implementa OnDestroy {

  constructor (renderizador privado: Renderer) {
    this.renderer.setElementClass (document.body, 'modal-open', true);
   }

  ngOnDestroy () {
    this.renderer.setElementClass (document.body, 'modal-open', false);
  }

EDITAR PARA ANGULAR4:

importar {Component, OnDestroy, Renderer2} desde '@ angular / core';

export class myModalComponent implementa OnDestroy {

  constructor (renderizador privado: Renderer2) {
    this.renderer.addClass (document.body, 'modal-open');
   }

  ngOnDestroy () {
    this.renderer.removeClass (document.body, 'modal-open');
  }
DaniS
fuente
3
gracias por la respuesta, creo que usar el rendrer es la mejor solución
Rachid O
6
En caso de que alguien se pregunte dónde obtener el DOCUMENTO, es:import { DOCUMENT } from '@angular/platform-browser'
Neph
14
La solución Renderer es mucho mejor. En Angular 4, Renderer ha quedado obsoleto y reemplazado por Renderer2. El código tendría que cambiar a: this.renderer.addClass(document.body, 'modal-open'); ythis.renderer.removeClass(document.body, 'modal-open');
GreyBeardedGeek
3
Además, @Inject(DOCUMENT)ya no se necesita en el constructor
GreyBeardedGeek
3
Como actualización de @Neph: la importación de DOCUMENT desde el navegador de la plataforma está obsoleta. Utilice @ angular / common en su lugar.
Pieter De Bie
36

Creo que la mejor manera de hacerlo es una combinación de ambos enfoques de DaniS anterior: usar el renderizador para establecer / eliminar la clase, pero también usar el inyector de documentos, por lo que no depende en gran medida del window.documentpero que se puede reemplazar dinámicamente (por ejemplo, al renderizar el lado del servidor). Entonces, todo el código se vería así:

import { DOCUMENT } from '@angular/common';
import { Component, Inject, OnDestroy, OnInit, Renderer2 } from '@angular/core';

@Component({ /* ... */ })
export class MyModalComponent implements OnInit, OnDestroy {
    constructor (
        @Inject(DOCUMENT) private document: Document,
        private renderer: Renderer2,
    ) { }

    ngOnInit(): void {
        this.renderer.addClass(this.document.body, 'embedded-body');
    }

    ngOnDestroy(): void {
        this.renderer.removeClass(this.document.body, 'embedded-body');
    }
}
DHainzl
fuente
8
Gracias, gracias, gracias, gracias, gracias, gracias, gracias :)
Kamlesh