Я получаю фрагменты HTML-кода из HTTP-вызовов. Я помещаю блоки HTML в переменную и вставляю их на свою страницу с помощью [innerHTML], но я не могу стилизовать вставленный блок HTML. Есть ли у кого-нибудь предложения, как я могу этого добиться?

@ Компонент ({
  селектор: 'календарь',
  шаблон: '
', поставщики: [HomeService], стили: [`h3 {цвет: красный; } `] })

HTML, который я хочу стилизовать, - это блок, содержащийся в переменной «calendar».

Jakob Svenningsson

Ответов: 11

Ответы (11)

update 2 ::slotted

:: slotted теперь поддерживается всеми новыми браузерами и может использоваться с ViewEncapsulation.ShadowDom

https://developer.mozilla.org/en-US/docs/Web/CSS/:: прорези

обновление 1 :: ng-deep

/ deep / устарел и заменен на :: ng-deep.

:: ng-deep также уже помечено как устаревшее, но замены пока нет.

Когда ViewEncapsulation.Native правильно поддерживается всеми браузерами и поддерживает стили через границы теневой DOM, :: ng-deep, вероятно, будет прекращено.

original

• 100001 Angular также переписывает CSS, который вы добавляете, чтобы соответствовать этим добавленным классам. Для HTML, добавленного с использованием [innerHTML], эти классы не добавляются, и переписанный CSS не соответствует.

В качестве обходного пути попробуйте

  • для CSS добавлен в компонент
/ *: host / deep / mySelector {* /
: host :: ng-deep mySelector {
  цвет фона: синий;
}
  • для CSS добавлен в index.html
/ * body / deep / mySelector {* /
body :: ng-deep mySelector {
  цвет фона: зеленый;
}

>>> (и эквивалент/ deep /, но / deep / лучше работает с SASS) и :: shadowбыли добавлены в 2.0.0-beta.10. Они похожи на комбинаторы CSS shadow DOM (которые устарели) и работают только с инкапсуляцией : ViewEncapsulation.Emulated, которая используется по умолчанию в Angular2. Вероятно, они также работают с ViewEncapsulation.None, но тогда игнорируются только потому, что в них нет необходимости. Эти комбинаторы являются лишь промежуточным решением до тех пор, пока не будут поддерживаться более продвинутые функции для кросс-компонентного стиля.

Другой подход - использовать

@ Компонент ({
  ...
  инкапсуляция: ViewEncapsulation.None,
})

для всех компонентов, которые блокируют ваш CSS (зависит от того, где вы добавляете CSS и где находится HTML, который вы хотите стилизовать - может быть все компоненты в вашем приложении)

Обновить

Пример Plunker

Самый простой и понятный - использовать файл глобальных стилей, расположенный в папке src проекта angular.

Предполагается, что селектор компонентов: app-my-component

Добавьте класс к элементу, содержащему содержимое innerHtml в шаблоне app-my-component:

Добавить в файл глобальных стилей:

app-my-component { 
 .innerhtml-class { 
   declaration goes here 
 } 
}

Сначала я пошел по маршруту this.sanitizer.bypassSecurityTrustHtml () и установил инкапсуляцию на ViewEncapsulation.NONE, но имел 2 проблемы:

  1. ViewEncapsulation.NONE вызывал другие проблемы со стилем в моем компоненте
  2. Мой "безопасный" html не работал с переменными css, т.е. var (- blue)

Это сработало для меня (без необходимости ничего менять): InsertAdjacentHTML

Шаблон:

Код:

ngOnInit() {
  const el = document.getElementById('template');
  el.insertAdjacentHTML('afterbegin', `hello`);
}

Заявление об ограничении ответственности: В моем случае я разбирал html из файлов конфигурации. Вы бы не хотели идти по этому пути с введенным пользователем html.

Используйте метод ниже, чтобы разрешить стили CSS в innerhtml.

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
.
.
.
.
html: SafeHtml;

constructor(protected _sanitizer: DomSanitizer) {
   this.html = this._sanitizer.bypassSecurityTrustHtml(`
        
        
        
           

Hello World..!!!!!

`); }

Пример кода stackblitz

Или используйте метод ниже, чтобы писать прямо в HTML. https://gist.github.com/klihelp/4dcac910124409fa7bd20f230818c8d1

Если вы используете sass в качестве препроцессора стилей, вы можете переключиться обратно на собственный компилятор Sass для зависимости от разработчиков:

npm install node-sass --save-dev

Чтобы вы могли продолжать использовать / deep / для разработки.

Мы часто получаем контент из нашей CMS как [innerHTML] = "content.title". Мы размещаем необходимые классы в корневом файле приложения styles.scss, а не в scss-файле компонента. Наша CMS намеренно удаляет встроенные стили, поэтому мы должны подготовить классы, которые автор может использовать в своем контенте. Помните, что использование {{content.title}} в шаблоне не будет отображать HTML из содержимого.

Использование встроенных переменных CSS является альтернативным решением, если у вас есть ограниченные стили, которые являются динамическими.

То есть

// file.ts
someVarWithHtml = 'Hello World';

// file.ng.html
// style.css .dynamic { background: var(--my-var); }

Рекомендуемая версия Günter Zöchbauer работает нормально, но мне нужно сделать дополнение. В моем случае у меня был нестилизованный html-элемент, и я не знал, как его стилизовать. Поэтому я разработал канал, чтобы добавить к нему стиля.

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';


@Pipe({
    name: 'StyleClass'
})
export class StyleClassPipe implements PipeTransform {

    constructor(private sanitizer: DomSanitizer) { }
    transform(html: any, styleSelector: any, styleValue: any): SafeHtml {
        const style = ` style = "${styleSelector}: ${styleValue};"`;
        const indexPosition = html.indexOf('>');
        const newHtml = [html.slice(0, indexPosition), style, html.slice(indexPosition)].join('');
        return this.sanitizer.bypassSecurityTrustHtml(newHtml);
    }

}

Затем вы можете добавить стиль к любому html-элементу следующим образом:

 

С:

Variable = '

Test

'

Если вы пытаетесь стилизовать динамически добавленные элементы HTML внутри компонента Angular, это может быть полезно:

// внутри класса компонента ...
    
конструктор (частный hostRef: ElementRef) {}
    
getContentAttr (): string {
  const attrs = this.hostRef.nativeElement.attributes
  for (let i = 0, l = attrs.length; i 

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

The simple solution you need to follow is

import { DomSanitizer } from '@angular/platform-browser';

constructor(private sanitizer: DomSanitizer){}

transformYourHtml(htmlTextWithStyle) {
    return this.sanitizer.bypassSecurityTrustHtml(htmlTextWithStyle);
}

Для всех, кто хочет просто применить определенный стиль к innerHTML:

Follow Создать безопасный канал HTML

И вы можете объединить свою HTML-строку со стилем CSS следующим образом:

return this.sanitizer.bypassSecurityTrustHtml(value+='');

Это значение взято из transform (value, ... args)

2022 WebDevInsider