cob*_*nks 6 angular2-template angular
我想创建一个通用的html片段组件.我们的想法是将html片段存储在db中的某个地方,以及应该应用于它们的样式.
我可以轻松设置innerHtml以将html结构插入到我的视图模板中的基本元素中,但是如何在我的视图模板中动态插入<style>标记?
这就是我所拥有的:
@Component({
moduleId: module.id,
selector: 'htmlFragment',
styleUrls: ['html-fragment.css'],
templateUrl:'html-fragment.html'
})
export class HtmlFragmentComponent {
@Input() htmlContent: string;
@Input() styleContent: string;
}
Run Code Online (Sandbox Code Playgroud)
这是视图模板:
<style [innerHTML]="styleContent"></style>
<div [innerHTML]="htmlContent"></div>
Run Code Online (Sandbox Code Playgroud)
然后我试着像这样使用它:
<htmlFragment [htmlContent]='dHtml' [styleContent]="sHtml"></htmlFragment>
Run Code Online (Sandbox Code Playgroud)
哪里:
dHtml: string = '<div>hello this is html<ul><li>bla bla</li><li>bla bla 2</li></ul></div>';
sHtml: string = 'ul{list-style-type: none;}';
Run Code Online (Sandbox Code Playgroud)
html片段在这里正确注入:
<div [innerHTML]="htmlContent"></div>
Run Code Online (Sandbox Code Playgroud)
但是这里的样式元素:
<style [innerHTML]="styleContent"></style>
Run Code Online (Sandbox Code Playgroud)
工作不对.有没有办法做到这一点?
ebr*_*ult 15
它不能在模板本身中完成(Angular模板编译器不允许它,并且只删除任何<style>标记),但它可以在组件内以编程方式完成:
ngOnInit() {
const css = 'a {color: pink;}';
const head = document.getElementsByTagName('head')[0];
const style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
head.appendChild(style);
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,Angular会吞噬<style>元素并将其放入默认的Angular CSS管道中。您可以通过以下方法绕过此方法:
@Component({
template: `<div [innerHTML]="styles"></div>`
})
export class OutputStyleTagComponent implements OnInit {
public styles: SafeHtml;
constructor(
private sanitizer: DomSanitizer
) {}
ngOnInit() {
this.styles = this.sanitizer.bypassSecurityTrustHtml(`
<style>
.my-styles {
...
}
</style>
`);
}
}
Run Code Online (Sandbox Code Playgroud)
它具有缺点,例如需要包装div容器。您还必须确保您不允许用户在此标记中提交内容,因为它使您容易受到XSS攻击。如果必须,则需要先确保内容安全,然后再将其传递到bypassSecurityTrustHtml中。
与OP相关,我不推荐以下绕过(或该线程中的任何其他绕过),但为了完整性我将其放在这里。推荐的解决方案是将 .scss / .css / .html 单独存储在数据库中 - 运行服务器端 gulp 任务并编译模块并延迟加载它们(然后支持 Shadow-dom,没有安全问题,等等)的多功能性)。
无论如何,有很多原因可以解释为什么将样式放入模板中(通过注入或其他方式)是一种不好的做法,包括违反封装等。
以这种方式应用的样式是全局应用的样式。这可能比使用keepStyle管道更有利,或者[attr.style]因为它允许角度计算的样式表,!important如果在库或其他地方使用它,则可以在外部使用该样式表进行覆盖。直接应用于style属性的样式不能被外部 CSS 覆盖。
<style>无论如何,除了序言之外,您可以通过将标签放置在标签中来防止删除标签<svg>,例如:
<svg>
<style>
.global-style-x {
transform: rotate({{someAngleComputation}}deg);
}
</style>
</svg>
<button class="global-style-x">
</button>
Run Code Online (Sandbox Code Playgroud)
同样,这些在模板中插入样式的方法都不是最佳实践。
[innerHTML]='styleTag | keepHtml")。@ZachDahl 和 @JuliaPassynkova 解决方案使用或不使用管道(例如[attr.style]="style | keepStyle"or [innerHTML]="yourStyleTag | keepHTML"-...)正在绕过安全设备并造成注入攻击的潜在威胁。
| 归档时间: |
|
| 查看次数: |
4194 次 |
| 最近记录: |