防止添加了 innerHtml 的 child 组件 <style> 应用于 parent

Prevent child component <style> added with innerHtml to be applied to parent

如何防止使用 innerHtml 添加到 child 的 child 组件样式应用于 parent?巧合的是,parent 可能已经有一个同名的 css class。如果 ViewEncapsulation 设置为 Native,这似乎可以正常工作(child 有红色背景,parent 有绿色),但使用 Emulated 则不然。不能用Native,据说不是所有浏览器都支持

app.ts

import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule, DomSanitizer} from '@angular/platform-browser'
import {Component, Input, ViewEncapsulation} from '@angular/core'

@Component({
  selector: 'my-app',
  template: `<div class="header">
    <h2>Hello {{name}}</h2>
</div>
<hr>
  <child [content]="content"></child>
`,

})

export class App {
  name:string;
  content:string = '<style>.header {background-color:red;color:white;}</style><div class="header">This is child content</div>'
  constructor(public ds: DomSanitizer) {
    this.content = this.ds.bypassSecurityTrustHtml(this.content);
    this.name = `Angular! v${VERSION.full}`
  }
}

@Component({
  selector: 'child',
  template:`<div [innerHtml]="content"></div>`,
  encapsulation:ViewEncapsulation.Emulated
//  encapsulation:ViewEncapsulation.Native
})
export class child{
 @Input('content') content;

}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, child ],
  bootstrap: [ App ]
})
export class AppModule {}

style.css

.header {
      background-color:green;
      color:white;
} 

Plunker example

任何组件都应该有自己的样式表。在那里你可以添加这样的东西:

:host {
  //styling
}
:host > div { //etc }

带有 :host 的任何内容都适用于该组件。这不能解决您的问题吗?

例如,如果您知道要添加什么结构,则可以将其写入组件装饰器:

@Component({
  selector: 'child',
  template: `<div [innerHtml]="content"></div>`,
  encapsulation: ViewEncapsulation.Emulated,
  styles: [ ':host { position: absolute; top: 10%; }' ]
})

然后您仍然可以添加您的 innerHtml 并且样式将应用于它。因此在上述情况下,当组件部署在 DOM 中时,:host {} 样式应该应用于该组件。从那时起,如果您知道 structure/tags/classes 您的 innerHtml 将包含什么,那么这只是它们的样式问题。

或者。而不是像上面那样的样式,将其更改为自己的样式表:

  styleUrls: ['/some/path/to/stylesheet.css']

我的发现:(Angular5)Emulate封装不行,因为只在编译时应用,Native是在运行时应用,但是不能用,因为不支持跨浏览器。由于 angular 在运行时不控制 innerHtml,因此 html 直接插入到 dom 中,这可能导致 类 具有现有名称,被插入的 [=12 无意中覆盖=]. 所以目前,避免此问题的唯一解决方案是在将 css 插入 dom 之前手动重命名 css 类 及其在 html 中的引用。当在样式装饰器中指定 :host 时,这就是 angular 隔离 css 的作用。目前也没有办法在运行时触发 angular 对自定义 css/html 字符串的编译,这会为我们重命名,尽管功能显然存在。