样式化 HTML 内容使用 Angular 2 随选项卡动态切换

Styled HTML content dynamically switched with tabs using Angular 2

我正在尝试创建一个可重复使用的 angular2 组件,该组件接受指向我服务器上 html 文件的一组 URL,并创建一个内容 window,其中包含用于在 "chapters",有效地交换了内容 window 中的 html 和 css。我已经尝试了各种方法,包括 iframe,但它们不起作用,我可以在 Whosebug 上找到的 angular 1 ng-include 解决方法,但它们都已被弃用,而我得到的最接近的方法正在构建一个您可以 @Input html 的组件,它会插入内容但样式不会应用,并且 angular 会删除任何样式或脚本标签。这是我试过的。

在我的父组件中 class:

htmlInput: string = "<h1>Why Does Angular make this so hard?</h1>";
cssInput: string = "h1 { color:red; }"

父组件HTML:

<app-html [html]='htmlInput' [css]='cssInput'></app-html>

我的HTML组件:

import { Component, Input, OnInit } from '@angular/core';

@Component({
    selector: 'app-html',
    template: '<div [innerHtml]=html></div>', //This works but no style
    //template: '{{html}}', //This displays the actual markup on page
    styles: ['{{css}}'] //This does nothing
    //styles: ['h1 { color: red; }']//Also nothing
})
export class HtmlComponent implements OnInit {
    @Input() html: string = "";
    @Input() css: string = "";
    ngOnInit() {

    }
}

这段代码的结果是

为什么 Angular 让它变得如此困难?

但是没有红色。也许在将 innerHtml 添加到 DOM 之前应用了样式?我不知道,只是放置 {{html}} 会导致显示带有可见 h1 标签的实际标记。

我想这样做的原因是,在我 angular 化我的网站之前,我已经在我的服务器上的一个文件夹中创建了一堆 HTML 页面,这些页面都是共享的单一样式 sheet。我希望能够像翻阅书页一样浏览它们而无需重新加载页面,因为有这么多而且我可能会一直添加更多,我真的不想为每一个创建路由一。 (我已经有了用于基本站点导航的路由。)

对于如何在最新版本的 Angular 2 中动态嵌入样式 HTML 到页面中,有没有人有更好的建议?此时 post 我们处于 2.0.0-beta.17。

或者...我已经意识到我可能从完全错误的角度来处理这个问题。肯定有一个原因 Angular 使这变得如此困难并且反对人们提出的所有解决方案所以如果有人对我如何以更 angular 友好的方式实现相同的结果有建议我我也很想听听。

谢谢。

编辑:

我能够通过创建一个管道来解决我的问题,该管道在将 html 添加到 iframe 之前对其进行消毒。

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({ name: 'safe' })
export class SafePipe implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) {}
  transform(url: string) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}

然后您可以将 html 传递到 iframe 中。

<iframe width="100%" height="1000" frameBorder="0" [src]="url | safe"></iframe>

这对我很有用,因为我有一些旧页面使用了各种 jquery 和样式等。这是让它们显示出来的快速修复方法。

您应该将 css 包装到一个对象中并使用 ngStyle 将其绑定到您的组件而不是 styles 属性,因为 styles 不支持数据绑定。

示例:

htmlInput: string = "<h1>Why Does Angular make this so hard?</h1>";
cssInput: string = "{h1 { color:red; }}"

父组件HTML:

<app-html [html]='htmlInput' [css]='cssInput'></app-html>

您的 HTML 组件:

import { Component, Input, OnInit } from '@angular/core';

@Component({
    selector: 'app-html',
    template: '<div [innerHtml]="html" [ngStyle]="css"></div>',
    styles: []
})
export class HtmlComponent implements OnInit {
    @Input() html: string = "";
    @Input() css: string = "";
    ngOnInit() {

    }
}

Angular2 通过将 _ngcontent-yle-18 等动态添加的属性包含到 CSS 选择器中来重写添加到组件的样式。

Angular2 使用它来模拟阴影 DOM 样式封装。这些属性不会添加到动态添加的 HTML(例如 innerHTML)。

解决方法

  • index.html添加样式,因为这些样式没有被Angular2

  • 重写
  • 设置ViewEncapsulation.None因为Angular不添加封装仿真属性

  • 使用/deep/使Angular2忽略封装模拟属性

另见