我正在写一个Angular应用程序,我有一个HTML响应,我想显示。

我怎么做呢?如果我简单地使用绑定语法{{myVal}},它将编码所有HTML字符(当然)。

我需要以某种方式将一个div的innerHTML绑定到变量值。


当前回答

Angular 2.0.0和Angular 4.0.0 final

对于安全的内容

<div [innerHTML]="myVal"></div>

DOMSanitizer

潜在的不安全HTML需要使用angular的DOM杀毒器显式地标记为受信任,这样就不会剥离潜在的不安全内容

<div [innerHTML]="myVal | safeHtml"></div>

用一根管子

@Pipe({name: 'safeHtml'})
export class Safe {
  constructor(private sanitizer:DomSanitizer){}

  transform(style) {
    return this.sanitizer.bypassSecurityTrustHtml(style);
    //return this.sanitizer.bypassSecurityTrustStyle(style);
    // return this.sanitizer.bypassSecurityTrustXxx(style); - see docs
  }
}

在RC.1中,有些样式不能使用绑定语法添加

文档:https://angular.io/api/platform-browser/DomSanitizer

安全警告

相信用户添加的HTML可能会带来安全风险。之前提到的文档状态:

调用任意一个bypassSecurityTrust…api禁用Angular内置的对传入值的处理功能。仔细检查和审计进入此调用的所有值和代码路径。确保任何用户数据都为此安全上下文进行了适当的转义。更多详细信息请参见《安全指南》。

角标记

类似的

class FooComponent {
  bar = 'bar';
  foo = `<div>{{bar}}</div>
    <my-comp></my-comp>
    <input [(ngModel)]="bar">`;

with

<div [innerHTML]="foo"></div>

不会导致Angular在foo中处理任何特定于Angular的东西。 Angular在构建时用生成的代码替换Angular特定的标记。在运行时添加的标记不会被Angular处理。

要添加包含特定于angular的标记(属性或值绑定、组件、指令、管道等)的HTML,需要添加动态模块并在运行时编译组件。 如何在Angular 2.0中使用/创建动态模板来编译动态组件?

其他回答

动态添加元素到DOM的方法,正如在Angular 2文档中解释的那样,是使用@Angular/core中的ViewContainerRef类。

你要做的是声明一个指令,它将实现ViewContainerRef,并充当DOM上的占位符。

指令

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appInject]'
})
export class InjectDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}

然后,在你想要注入组件的模板中:

HTML

<div class="where_you_want_to_inject">    
  <ng-template appInject></ng-template>
</div>

然后,从注入的组件代码中,注入包含你想要的HTML的组件:

import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { InjectDirective } from '../inject.directive';
import { InjectedComponent } from '../injected/injected.component';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

  @ViewChild(InjectDirective) injectComp: InjectDirective;

  constructor(private _componentFactoryResolver: ComponentFactoryResolver) {
  }

  ngOnInit() {
  }

  public addComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.createComponent(componentFactory);
  }

  public removeComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.remove();
  }

}

我在Angular 2上添加了一个完全可用的演示应用,动态地将组件添加到DOM演示中

只是在目前为止所有精彩的回答中补充一点:如果你正在使用[innerHTML]来渲染Angular组件,并且对它不能像我一样工作感到沮丧,可以看看我写的ngx-dynamic-hooks库来解决这个问题。

有了它,您可以从动态字符串/html加载组件,而不会影响安全性。它实际上也像[innerHTML]一样使用Angular的DOMSanitizer,但保留了加载组件的能力(以一种安全的方式)。

在这部《斯塔克布利茨》中可以看到它的作用。

你可以使用以下两种方法。

<div [innerHTML]="myVal"></div>

or

<div innerHTML="{{myVal}}"></div>

你也可以使用DOM属性绑定将angular组件的类属性与模板绑定。

例如:<div [innerHTML]="theHtmlString"></div>

使用规范形式如下:

<div bind-innerHTML="theHtmlString"></div>

Angular文档:https://angular.io/guide/template-syntax#property-binding-property

参见工作stackblitz示例

为了得到一个完整的答案,如果你的HTML内容是在一个组件变量中,你也可以使用:

<div [innerHTML]=componentVariableThatHasTheHtml></div>