Angular 2-innerHTML样式


170

我从HTTP调用中获取了很多HTML代码。我将HTML块放入变量中,并使用[innerHTML]将其插入到我的页面中,但是我无法为插入的HTML块设置样式。有人对我如何实现这一目标有任何建议吗?

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

我要设置样式的HTML是变量“ calendar”中包含的块。


风格从哪里来?从组件内部还是从添加样式index.html
君特Zöchbauer

你是什​​么意思can not style the inserted HTML block?用一小段代码向我们展示该功能。
micronyks

香港专业教育学院更新了我的代码片段!:)谢谢
Jakob Svenningsson

1
我添加了一个Plunker链接到我的答案
君特Zöchbauer

@GünterZöchbauer如果HTML代码具有内联CSS怎么办?它将如何呈现?
iniravpatel

Answers:


320

更新2 ::slotted

::slotted 现在,所有新浏览器都支持该功能,并且可以与 ViewEncapsulation.ShadowDom

https://developer.mozilla.org/zh-CN/docs/Web/CSS/::slotted

更新1 :: ng-deep

/deep/已淘汰,并由取代::ng-deep

::ng-deep 也已被标记为已弃用,但尚无替代品。

ViewEncapsulation.Native所有浏览器都正确支持并且支持跨阴影DOM边界的样式时,::ng-deep可能会停止使用。

原版的

Angular将各种CSS类添加到HTML中,并将其添加到DOM中以模拟影子DOM CSS封装,以防止样式渗入和渗出组件。Angular还会重写您添加的CSS以匹配这些添加的类。对于使用[innerHTML]这些类添加的HTML ,不会添加它们,并且重写的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中添加。它们类似于Shadow DOM CSS组合器(已弃用),并且仅与encapsulation: ViewEncapsulation.EmulatedAngular2中的默认组合器一起使用。它们可能也与之一起工作,ViewEncapsulation.None但由于没有必要,因此仅被忽略。在支持跨组件样式的更高级功能之前,这些组合器只是一个中间解决方案。

另一种方法是使用

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

适用于所有阻止CSS的组件(取决于添加CSS的位置以及要设置HTML样式的位置-可能是应用程序中的所有组件)

更新资料

柱塞示例


6
只是对任何人的注释,它不适用于node-sass或styleUrl。仅在以下样式中:[...]
thouliha

12
随着SASS使用/deep/代替>>>
冈特Zöchbauer

1
您can'r有增加的指令或内容compinentsinneeHTML
君特Zöchbauer

1
如果通过HTTP提供的HTML调用大,它有内联CSS这将如何是可能的我没有风格预定义的,我得到它从内联CSS只@GünterZöchbauer
iniravpatel

1
在Angular 8中保存了一天!谢谢 很难找到正确的问题才能找到答案!
钢琴家

12

您需要遵循的简单解决方案是

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

constructor(private sanitizer: DomSanitizer){}

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

2

如果您尝试在Angular组件中为动态添加的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编译器以获取dev依赖性:

npm install node-sass --save-dev

这样您就可以继续使用/ deep /进行开发。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.