Angular2 aggiunge la classe al tag del corpo


98

Come posso aggiungere una classe al tag body senza impostare il body come selettore di app e utilizzare l'associazione host?

Ho provato a utilizzare il Renderer ma cambia tutto il corpo

Classe di associazione angolare 2.x sul tag body

Sto lavorando su una grande app angular2 e la modifica del selettore di root avrà un impatto su molto codice, dovrò cambiare molto codice

Il mio caso d'uso è questo:

Quando apro un componente modale (creato dinamicamente) desidero nascondere la barra di scorrimento del documento


1
In realtà se lavori con js all'interno di una pagina html qual è il problema con l'utilizzo document.body.className|classList?
yurzui

haha se solo fosse così semplice :) ma è una cattiva pratica accedere direttamente a dom
Rachid O

Puoi scrivere un grande wrapper che verrà eseguito diversi secondi e alla fine aggiunto classa body. Se non intendi utilizzare il rendering del server o il web worker, di cosa hai paura?
yurzui

quindi non c'è soluzione migliore di questa?
Rachid O

4
Non riesco a capire queste persone violente che votano negativamente e chiudono domande senza un motivo valido
Rachid O

Risposte:


214

Mi piacerebbe commentare. Ma a causa della mancanza di reputazione scrivo una risposta. Beh, conosco due possibilità per risolvere questo problema.

  1. Iniettare il documento globale. Beh, potrebbe non essere la migliore pratica in quanto non so se nativescript ecc lo supporti. Ma è almeno meglio che usare JS puro.
costruttore (documento privato @Inject (DOCUMENT): Document) {}

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

Bene e forse anche meglio. Potresti iniettare il renderer o renderer 2 (su NG4) e aggiungere la classe con il renderer.

export class myModalComponent implementa OnDestroy {

  costruttore (renderer privato: Renderer) {
    this.renderer.setElementClass (document.body, 'modal-open', true);
   }

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

MODIFICA PER ANGOLARE4:

import {Component, OnDestroy, Renderer2} da "@ angular / core";

export class myModalComponent implementa OnDestroy {

  costruttore (renderer privato: Renderer2) {
    this.renderer.addClass (document.body, 'modal-open');
   }

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

3
grazie per la risposta, penso che usare il renderer sia la soluzione migliore
Rachid O

6
Nel caso qualcuno si chiedesse dove prendere il DOCUMENTO, questo è:import { DOCUMENT } from '@angular/platform-browser'
Neph

14
La soluzione Renderer è molto migliore. In Angular 4, Renderer è stato deprecato e sostituito con Renderer2. Il codice dovrebbe cambiare in: this.renderer.addClass(document.body, 'modal-open'); ethis.renderer.removeClass(document.body, 'modal-open');
GreyBeardedGeek

3
Inoltre, @Inject(DOCUMENT)non è più necessario nel costruttore
GreyBeardedGeek

3
Come aggiornamento a @Neph: l'importazione di DOCUMENTO dal browser della piattaforma è deprecata. Usa invece @ angular / common.
Pieter De Bie

36

Penso che il modo migliore per farlo sia una combinazione di entrambi gli approcci di DaniS sopra: utilizzare il renderer per impostare / rimuovere effettivamente la classe, ma anche utilizzare l'iniettore di documenti, quindi non è fortemente dipendente dal window.documentma può essere sostituito dinamicamente (ad esempio quando si esegue il rendering lato server). Quindi l'intero codice sarebbe simile a questo:

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');
    }
}

8
Grazie, grazie, grazie, grazie, grazie, grazie, grazie :)
Kamlesh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.