防止添加了 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;
}
任何组件都应该有自己的样式表。在那里你可以添加这样的东西:
: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 字符串的编译,这会为我们重命名,尽管功能显然存在。
如何防止使用 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;
}
任何组件都应该有自己的样式表。在那里你可以添加这样的东西:
: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 字符串的编译,这会为我们重命名,尽管功能显然存在。