Angular2 fügt dem Body-Tag eine Klasse hinzu

97

Wie kann ich dem Body- Tag eine Klasse hinzufügen, ohne den Body als App-Selektor festzulegen und die Host-Bindung zu verwenden?

Ich habe versucht, den Renderer zu verwenden, aber er verändert den ganzen Körper

Angular 2.x-Bindungsklasse für Body-Tag

Ich arbeite an einer großen Angular2-App und das Ändern des Root-Selektors wirkt sich auf viel Code aus. Ich muss viel Code ändern

Mein Anwendungsfall ist folgender:

Wenn ich eine modale Komponente öffne (dynamisch erstellt), soll die Dokument-Bildlaufleiste ausgeblendet werden

Rachid O.
quelle
1
Wenn Sie mit js innerhalb einer HTML-Seite arbeiten, was ist das Problem bei der Verwendung document.body.className|classList?
Yurzui
haha wenn es nur so einfach wäre :) aber es ist eine schlechte Praxis direkt auf dom zuzugreifen
Rachid O
Sie können einen großen Wrapper schreiben , die mehr zweiten und am Ende ausgeführt werden hinzugefügt classzu body. Wenn Sie kein Server-Rendering oder keinen Web-Worker verwenden, wovor haben Sie Angst?
Yurzui
Es gibt also keine bessere Lösung als diese?
Rachid O
4
Ich kann diese missbräuchlichen Menschen nicht verstehen, die Fragen ohne triftigen Grund ablehnen und schließen
Rachid O.

Antworten:

212

Ich würde gerne einen Kommentar abgeben. Aber wegen fehlenden Rufs schreibe ich eine Antwort. Nun, ich kenne zwei Möglichkeiten, um dieses Problem zu lösen.

  1. Injizieren Sie das globale Dokument. Nun, es ist möglicherweise nicht die beste Vorgehensweise, da ich nicht weiß, ob Nativescript usw. dies unterstützt. Aber es ist zumindest besser als reines JS zu verwenden.
Konstruktor (@Inject (DOCUMENT) privates Dokument: Dokument) {}

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

Gut und vielleicht sogar noch besser. Sie können den Renderer oder Renderer 2 (auf NG4) einfügen und die Klasse mit dem Renderer hinzufügen.

Exportklasse myModalComponent implementiert OnDestroy {

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

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

BEARBEITEN FÜR ANGULAR4:

{Component, OnDestroy, Renderer2} aus '@ angle / core' importieren;

Exportklasse myModalComponent implementiert OnDestroy {

  Konstruktor (privater Renderer: Renderer2) {
    this.renderer.addClass (document.body, 'modal-open');
   }}

  ngOnDestroy () {
    this.renderer.removeClass (document.body, 'modal-open');
  }}
DaniS
quelle
3
Vielen Dank für die Antwort, ich denke, die Verwendung des Rendrer ist die beste Lösung
Rachid O
6
Falls sich jemand fragt, wo er das import { DOCUMENT } from '@angular/platform-browser'
DOKUMENT
14
Die Renderer-Lösung ist viel besser. In Angular 4 wurde Renderer veraltet und durch Renderer2 ersetzt. Der Code müsste geändert werden zu: this.renderer.addClass(document.body, 'modal-open'); undthis.renderer.removeClass(document.body, 'modal-open');
GreyBeardedGeek
3
Auch @Inject(DOCUMENT)wird im Konstruktor nicht mehr benötigt
GreyBeardedGeek
3
Als Update zu @Neph: Der Import von DOCUMENT aus dem Plattform-Browser ist veraltet. Verwenden Sie stattdessen @ angle / common.
Pieter De Bie
36

Ich denke, der beste Weg, dies zu tun, ist eine Kombination beider Ansätze von DaniS oben: Verwenden des Renderers zum tatsächlichen Festlegen / Entfernen der Klasse, aber auch Verwenden des Dokumentinjektors, sodass es nicht stark von dem abhängt, window.documentsondern dynamisch ersetzt werden kann (zB beim Rendern serverseitig). Der gesamte Code würde also so aussehen:

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
quelle
8
Danke, danke, danke, danke, danke, danke, danke :)
Kamlesh