Angular2 adiciona classe à tag do corpo


98

Como posso adicionar uma classe à tag do corpo sem tornar o corpo como o seletor de aplicativo e usando a vinculação do host?

Eu tentei usar o Renderer, mas mudou todo o corpo

Classe de vinculação Angular 2.x na tag do corpo

Estou trabalhando em um grande aplicativo angular2 e alterar o seletor de raiz impactará muito código, terei que alterar muito código

Meu caso de uso é este:

Quando eu abro um componente modal (criado dinamicamente), quero que a barra de rolagem do documento oculte


1
Na verdade, se você trabalha com js dentro da página html, qual é o problema em usar document.body.className|classList?
— yurzui de

haha se fosse tão simples assim :) mas é uma má prática acessar o dom diretamente
— Rachid O

Você pode escrever um grande wrapper que será executado vários segundo e no final adicionado classa body. Se você não vai usar renderização de servidor ou web worker, do que você tem medo?
— yurzui de

então não há solução melhor do que essa?
— Rachid O de

4
Não consigo entender essas pessoas abusivas que votam negativamente e fecham as perguntas sem nenhum motivo válido
— Rachid O,

Respostas:


214

Eu adoraria comentar. Mas devido à falta de reputação, escrevo uma resposta. Bem, eu conheço duas possibilidades para resolver esse problema.

  1. Injete o documento global. Bem, pode não ser a melhor prática, pois não sei se o nativescript etc suporta isso. Mas é pelo menos melhor do que usar JS puro.
construtor (@Inject (DOCUMENT) documento privado: Documento) {}

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

Bem e talvez até melhor. Você pode injetar o renderizador ou o renderizador 2 (no NG4) e adicionar a classe com o renderizador.

export class myModalComponent implementa OnDestroy {

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

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

EDITAR PARA ANGULAR4:

import {Component, OnDestroy, Renderer2} de '@ angular / core';

export class myModalComponent implementa OnDestroy {

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

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

3
obrigado pela resposta, acho que usar o rendrer é a melhor solução
— Rachid O

6
Caso alguém esteja se perguntando onde conseguir o DOCUMENTO, é:import { DOCUMENT } from '@angular/platform-browser'
— Neph

14
A solução Renderer é muito melhor. No Angular 4, o Renderer foi descontinuado e substituído pelo Renderer2. O código teria que mudar para: this.renderer.addClass(document.body, 'modal-open'); ethis.renderer.removeClass(document.body, 'modal-open');
— GreyBeardedGeek

3
Além disso, @Inject(DOCUMENT)não é mais necessário no construtor
— GreyBeardedGeek

3
Como uma atualização para @Neph: importar DOCUMENT do navegador da plataforma está obsoleto. Use @ angular / common.
— Pieter De Bie

36

Acho que a melhor maneira de fazer isso é uma combinação de ambas as abordagens do DaniS acima: usando o renderizador para realmente definir / remover a classe, mas também usando o injetor de documentos, por isso não é fortemente dependente do, window.documentmas pode ser substituído dinamicamente (por exemplo, ao renderizar do lado do servidor). Portanto, todo o código ficaria assim:

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
Obrigado, obrigado, obrigado, obrigado, obrigado, obrigado, obrigado :)
— Kamlesh
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.