Angular2 добавить класс в тег тела

101

Как я могу добавить класс в тег тела, не используя тело в качестве селектора приложения и используя привязку хоста?

Я пробовал использовать Renderer, но он меняет все тело

Angular 2.x класс привязки к тегу body

Я работаю над большим приложением angular2, и изменение корневого селектора повлияет на много кода, мне придется изменить много кода

Мой вариант использования таков:

Когда я открываю модальный компонент (созданный динамически), я хочу, чтобы полоса прокрутки документа скрывала

Рашид О
источник
1
На самом деле, если вы работаете с js на странице html, в чем проблема с использованием document.body.className|classList?
yurzui
ха-ха, если бы это было так просто :) но прямой доступ к dom
Rachid O
Вы можете написать большую оболочку, которая будет выполняться несколько секунд и в конце добавляться classк body. Если вы не собираетесь использовать серверный рендеринг или веб-воркер, чего вы боитесь?
yurzui
так что нет лучшего решения, чем это?
Rachid O
4
Я не могу понять этих оскорбительных людей, которые голосуют против и закрывают вопросы без уважительной причины,
Рашид О.

Ответы:

218

Я хотел бы прокомментировать. Но из-за пропавшей репутации пишу ответ. Я знаю две возможности решить эту проблему.

  1. Внедрить глобальный документ. Что ж, это может быть не лучшая практика, поскольку я не знаю, поддерживает ли это nativescript и т. Д. Но это как минимум лучше, чем использовать чистый JS.
constructor (@Inject (DOCUMENT) закрытый документ: Document) {}

ngOnInit () {
   this.document.body.classList.add ('тест');
}

Ну а может даже лучше. Вы можете внедрить рендерер или рендерер 2 (на NG4) и добавить класс с рендерером.

класс экспорта myModalComponent реализует OnDestroy {

  конструктор (частный рендерер: рендерер) {
    this.renderer.setElementClass (document.body, 'модально-открытый', истина);
   }

  ngOnDestroy () {
    this.renderer.setElementClass (document.body, 'модальное открытие', ложь);
  }

РЕДАКТИРОВАТЬ ДЛЯ ANGULAR4:

импортировать {Component, OnDestroy, Renderer2} из '@ angular / core';

класс экспорта myModalComponent реализует OnDestroy {

  конструктор (частный рендерер: Renderer2) {
    this.renderer.addClass (document.body, 'модально-открытый');
   }

  ngOnDestroy () {
    this.renderer.removeClass (document.body, 'модально-открытый');
  }
ДаниС
источник
3
спасибо за ответ, я думаю, что использование rendrer - лучшее решение
Rachid O
6
Если кому-то интересно, где взять ДОКУМЕНТ, это:import { DOCUMENT } from '@angular/platform-browser'
Неф
15
Решение Renderer намного лучше. В Angular 4 Renderer устарел и заменен на Renderer2. Код должен быть изменен на: this.renderer.addClass(document.body, 'modal-open'); иthis.renderer.removeClass(document.body, 'modal-open');
GreyBeardedGeek
3
Кроме того, @Inject(DOCUMENT)больше не нужен конструктор
GreyBeardedGeek
3
В качестве обновления для @Neph: импорт ДОКУМЕНТА из браузера платформы устарел. Вместо этого используйте @ angular / common.
Pieter De Bie
40

Я думаю, что лучший способ сделать это - это комбинация обоих подходов DaniS, описанных выше: использование средства визуализации для фактической установки / удаления класса, а также использование инжектора документа, поэтому он не сильно зависит от, window.documentно может быть заменен динамически (например, при рендеринге на стороне сервера). Итак, весь код будет выглядеть так:

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
источник
9
Спасибо, спасибо, спасибо, спасибо, спасибо, спасибо, спасибо :)
Kamlesh