Кутова 2 - внутрішня HTML-укладка


170

Я отримую шматки HTML-кодів із HTTP-дзвінків. Я поміщаю HTML-блоки в змінну і вставляю її на свою сторінку за допомогою [innerHTML], але я не можу стилізувати вставлений HTML-блок. Хтось має якусь пропозицію, як я можу цього досягти?

@Component({selector: 'calendar',
template: '<div [innerHTML]="calendar"></div>',
providers:[HomeService], 
styles: [` 
h3 {color:red;}
`})

HTML, який я хочу стилізувати - це блок, що міститься у змінній "календар".


Стиль звідки? Зсередини компонента чи стилів, доданих до index.html?
Günter Zöchbauer

що ти маєш на увазі під собою can not style the inserted HTML block? Покажіть нам, що зробили для цього, за допомогою невеликого фрагмента коду.
мікроніки

Я оновив свою публікацію за допомогою фрагмента коду! :) дякую
Якоб Свеннінгссон

1
Я додав посилання на Plunker до своєї відповіді
Günter Zöchbauer

@ GünterZöchbauer, що якщо HTML-коди мають вбудований css? як це буде винесено?
iniravpatel

Відповіді:


320

оновлення 2 ::slotted

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

https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

оновлення 1 :: ng-deep

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

::ng-deep також вже позначено застарілим, але заміни ще немає.

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

оригінальний

Angular додає всі види CSS-класів до HTML, який додає до DOM, щоб імітувати тіньову інкапсуляцію CSS DOM для запобігання стилів кровотечі в компонентах та поза ними. Angular також переписує CSS, який ви додаєте, щоб відповідати цим доданим класам. Для HTML, доданих за допомогою [innerHTML]цих класів, не додається, і переписаний CSS не відповідає.

Як вирішити спробу

  • для CSS, доданого до компонента
/* :host /deep/ mySelector { */
:host ::ng-deep mySelector { 
  background-color: blue;
}
  • для CSS додано до index.html
/* body /deep/ mySelector { */
body ::ng-deep mySelector {
  background-color: green;
}

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

Інший підхід - використання

@Component({
  ...
  encapsulation: ViewEncapsulation.None,
})

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

Оновлення

Приклад Plunker


6
Просто примітка для когось, це не працює ні з node-sass, ні з styleUrl. Тільки в стилях: [...]
YOliha

12
З використанням SASS /deep/замість>>>
Günter Zöchbauer

1
Ви не можете мати директиви чи комп’ютери у вмісті, доданому доinneeHTML
Günter Zöchbauer

1
Якщо HTML, який надає HTTP-дзвінок, великий і він має вбудований css, як це стане можливим, оскільки я не маю заздалегідь визначені стилі, я отримую його лише з вбудованого CSS @ GünterZöchbauer
iniravpatel

1
Зберегли день у кутовій 8! Дякую. Важко правильно поставити питання, щоб знайти цю відповідь!
Піаноман

12

Просте рішення, яке вам потрібно дотримуватися, - це

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

constructor(private sanitizer: DomSanitizer){}

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

2

Якщо ви намагаєтеся стилістично додавати елементи HTML у кутовий компонент, це може бути корисно:

// inside component class...

constructor(private hostRef: ElementRef) { }

getContentAttr(): string {
  const attrs = this.hostRef.nativeElement.attributes
  for (let i = 0, l = attrs.length; i < l; i++) {
    if (attrs[i].name.startsWith('_nghost-c')) {
      return `_ngcontent-c${attrs[i].name.substring(9)}`
    }
  }
}

ngAfterViewInit() {
  // dynamically add HTML element
  dynamicallyAddedHtmlElement.setAttribute(this.getContentAttr(), '')
}

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


2

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


-3

Якщо ви використовуєте sass як препроцесор стилю, ви можете переключитися на початковий компілятор Sass для залежності від розробника:

npm install node-sass --save-dev

Так що ви можете продовжувати використовувати / глибокий / для розвитку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.