Кутова 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.