Angular HTML绑定

Avi*_* P. 756 angular2-template angular2-databinding angular

我正在写一个Angular应用程序,{{myVal}}我想要显示一个响应.

我怎么做?如果我只是使用绑定语法,innerHTML它会编码所有div字符(当然).

我需要以某种方式将a的内部html绑定{{myVal}}到变量值.

pro*_*007 1205

正确的语法如下:

<div [innerHTML]="theHtmlString"></div>
Run Code Online (Sandbox Code Playgroud)

在工作 8.2.13

文档参考

  • 有什么办法可以强制角度来运行它对innerHTML元素的绑定吗?我需要使用<a [router-link]="..."> </a>,并希望从外部html提供. (12认同)
  • 这很有帮助:http://victorsavkin.com/post/119943127151/angular-2-template-syntax (4认同)
  • @thouliha我建议你开一个关于你问题的新帖子. (4认同)
  • 它在我的情况下呈现字符串,但对标记做了一些事情.似乎已经剥离了标记上的属性.我在2.4.6 (4认同)
  • @paqogomez是的,它会删除任何它认为不安全的内容 (2认同)
  • @thouliha 你找到答案了吗?有什么方法可以强制角度在注入后重新评估绑定?我的所有绑定和模板都在innerHtml 部分中损坏 (2认同)
  • 其他答案 /sf/answers/2876236541/ 和 /sf/answers/2878470451/ 解决了安全 HTML 清理问题。 (2认同)
  • @jgritten 看看 https://www.npmjs.com/package/ngx-dynamic-hooks (2认同)

Gün*_*uer 287

Angular 2.0.0和Angular 4.0.0 final

仅为了安全的内容

<div [innerHTML]="myVal"></div>
Run Code Online (Sandbox Code Playgroud)

DOMSanitizer

潜在的不安全HTML需要使用Angulars DOM清理程序明确标记为受信任,因此不会删除内容中可能不安全的部分

<div [innerHTML]="myVal | safeHtml"></div>
Run Code Online (Sandbox Code Playgroud)

用管子

@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
  }
}
Run Code Online (Sandbox Code Playgroud)

另请参见在RC.1中,无法使用绑定语法添加某些样式

和文档:https://angular.io/api/platform-b​​rowser/DomSanitizer

安全警告

信任用户添加的HTML可能会带来安全风险.前面提到的文档陈述:

调用任何bypassSecurityTrust...API会禁用Angular对传入值的内置清理.仔细检查并审核进入此调用的所有值和代码路径.确保为此安全上下文适当地转义任何用户数据.有关详细信息,请参阅" 安全指南".

角度标记

就像是

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

<div [innerHTML]="foo"></div>
Run Code Online (Sandbox Code Playgroud)

不会导致Angular处理Angular特定的任何内容foo.Angular使用生成的代码替换构建时的Angular特定标记.Angular不会处理运行时添加的标记.

要添加包含特定于角度的标记(属性或值绑定,组件,指令,管道......)的HTML,需要在运行时添加动态模块和编译组件.这个答案提供了更多细节如何使用/创建动态模板来使用Angular 2.0编译动态组件?

  • 这应该是答案.注意注释掉的两行.它实际上是处理HTML的第二个. (12认同)
  • 一定要从'@ angular/platform-b​​rowser'`导入{BrowserModule,DomSanitizer} (8认同)
  • 还可以从'@ angular/core'`导入{Pipe} (4认同)
  • 很好的答案.解决了我的问题.非常感谢.如果有人不确定如何在组件中使用管道(就像我一样):https://angular.io/guide/pipes只需将它添加到相应模块中的声明中即可! (2认同)
  • 使用“DomSanitizer”代替 (2认同)
  • 这个答案解决了 HTML 产生的不安全问题。我设法定义文本颜色并添加一个 youtube“iframe”。您无法通过简单地设置innerHTML(如其他答案中所述)来实现此目的。 (2认同)

Pio*_*rek 161

[innerHtml] 在大多数情况下是很好的选择,但是它会因为非常大的字符串或者在html中需要硬编码样式而失败.

我想分享其他方法:

你需要做的就是在你的html文件中创建一个div并给它一些id:

<div #dataContainer></div>
Run Code Online (Sandbox Code Playgroud)

然后,在Angular 2组件中,创建对此对象的引用(此处为TypeScript):

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
    templateUrl: "some html file"
})
export class MainPageComponent {

    @ViewChild('dataContainer') dataContainer: ElementRef;

    loadData(data) {
        this.dataContainer.nativeElement.innerHTML = data;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后只需使用loadData函数将一些文本附加到html元素.

这只是一种使用原生javascript的方式,但在Angular环境中.我不推荐它,因为使代码更麻烦,但有时没有其他选择.

另请参见Angular 2 - innerHTML样式

  • `[innerHtml]`删除Html中硬编码的样式.为了集成一个所见即所得的编辑器,我不得不使用这里列出的方法. (24认同)
  • 其他解决方案首先将字符串保存到 html 属性,然后加载 html。将大字符串保存到属性会导致浏览器冻结甚至崩溃。我的解决方案省略了这个“属性部分” (2认同)
  • 对我来说,这个解决方案适用于包含内联SVG文档,而`[innerHTML]`方法则没有. (2认同)

jvo*_*igt 47

在angular2@2.0.0-alpha.44上:

使用时,Html-Binding不起作用{{interpolation}},改为使用"Expression":

无效

<p [innerHTML]="{{item.anleser}}"></p>
Run Code Online (Sandbox Code Playgroud)

- >抛出错误(插值而不是预期的表达式)

正确

<p [innerHTML]="item.anleser"></p>
Run Code Online (Sandbox Code Playgroud)

- >这是正确的方法.

您可以在表达式中添加其他元素,例如:

<p [innerHTML]="'<b>'+item.anleser+'</b>'"></p>
Run Code Online (Sandbox Code Playgroud)

暗示

除了用于安全目的的清理之外,Angular不会以任何方式处理使用[innerHTML](或通过其他类似element.appenChild()或类似的方式动态添加)添加的HTML .
只有将HTML静态添加到组件模板时,此类操作才有效.如果需要,可以在运行时创建一个组件,如我如何使用/创建动态模板以使用Angular 2.0编译动态组件中所述?

  • 第三个例子不起作用.表达式未评估.输出只是字符串...还有其他方法可以将trustedHTML与其他标签元素相结合吗? (2认同)

Ren*_*ger 23

如果它包含用户创建的内容,则不使用Angular的DOM清理程序直接使用[innerHTML].@GünterZöchbauer 在他的回答中提出的safeHtml管道是一种消毒内容的方法.以下指令是另一个指令:

import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
  SimpleChanges } from '@angular/core';

// Sets the element's innerHTML to a sanitized version of [safeHtml]
@Directive({ selector: '[safeHtml]' })
export class HtmlDirective implements OnChanges {
  @Input() safeHtml: string;

  constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}

  ngOnChanges(changes: SimpleChanges): any {
    if ('safeHtml' in changes) {
      this.elementRef.nativeElement.innerHTML =
        this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

要使用的

<div [safeHtml]="myVal"></div>
Run Code Online (Sandbox Code Playgroud)


Fan*_* Li 21

这对我<div innerHTML = "{{ myVal }}"></div>有用:(Angular2,Alpha 33)

根据另一个SO:使用angular2(在Angular2中的一般DOM操作)将HTML从服务器插入DOM,"inner-html"相当于Angular 1.X中的"ng-bind-html"

  • 使用[属性]绑定语法代替{{interpolation}} (2认同)

wat*_*lea 12

这里已经提供了简短的答案:使用<div [innerHTML]="yourHtml">绑定。

然而,这里提到的其余建议可能会产生误导。当你绑定到这样的属性时,Angular 有一个内置的清理机制。由于 Angular 不是一个专门的清理库,它对可疑内容过于热心,不承担任何风险。例如,它将所有 SVG 内容清理为空字符串。

您可能会听到建议,通过使用DomSanitizer方法将内容标记为安全来“清理”您的内容bypassSecurityTrustXXX。也有建议使用管道来做到这一点,管道通常被称为safeHtml.

所有这些都是误导性的,因为它实际上绕过了 sanitizing,而不是 sanitizing 您的内容。这可能是一个安全问题,因为如果您对用户提供的内容或您不确定的任何内容执行此操作,您就会面临恶意代码攻击。

如果 Angular 通过其内置的清理删除了你需要的东西——你可以做的而不是禁用它是将实际清理委托给擅长该任务的专用库。例如——DOMPurify。

我为它制作了一个包装库,因此它可以很容易地与 Angular 一起使用:https : //github.com/TinkoffCreditSystems/ng-dompurify

它还有一个管道来声明性地清理 HTML:

<div [innerHtml]="value | dompurify"></div>
Run Code Online (Sandbox Code Playgroud)

与此处建议的管道的不同之处在于,它实际上确实通过 DOMPurify 进行清理,因此适用于 SVG。

要记住的一件事是 DOMPurify 非常适合清理 HTML/SVG,但不是 CSS。所以你可以提供 Angular 的 CSS sanitizer 来处理 CSS:

import {NgModule, ?_sanitizeStyle} from '@angular/core';
import {SANITIZE_STYLE} from '@tinkoff/ng-dompurify';

@NgModule({
    // ...
    providers: [
        {
            provide: SANITIZE_STYLE,
            useValue: ?_sanitizeStyle,
        },
    ],
    // ...
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

它是内部的——hense?前缀,但这也是 Angular 团队在他们自己的包中使用它的方式。该库也适用于 Angular Universal 和服务器端渲染环境。


Ser*_*gan 11

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

<div [innerHTML]=componementVariableThatHasTheHtml></div>
Run Code Online (Sandbox Code Playgroud)


TGH*_*TGH 9

如果我在这里忽略了这一点,我道歉,但我想推荐一种不同的方法:

我认为最好从服务器端应用程序返回原始数据并将其绑定到客户端的模板.由于您只从服务器返回json,因此这会产生更灵活的请求.

对我来说,如果您正在做的就是从服务器获取html并将其"按原样"注入DOM中,那么使用Angular似乎没有意义.

我知道Angular 1.x有一个html绑定,但我还没有看到Angular 2.0中的对应物.他们可能会在以后添加它.无论如何,我仍然会考虑为你的Angular 2.0应用程序提供数据api.

如果您有兴趣,我在这里有一些示例带有一些简单的数据绑定:http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

  • 肯定会出现用于获取和显示原始html的用例.例如从远程获取格式化的文章. (26认同)
  • 另一个经常被忽略的场景是保护模板中的业务逻辑,有时您不希望未经授权的用户看到您用来显示信息的逻辑,因此您宁愿在服务器端准备视图 (2认同)
  • 此外,显示HTML电子邮件,例如 - 公平点/问题虽然! (2认同)
  • 如果您错过了要点(您似乎已经承认了这一点),那么为什么要发表答复?显然,Angular的要点是使用其视图引擎来绑定和呈现数据。但是考虑到有无数的应用程序可以使用Angular应用程序这一事实,实际上可行的是,其中一个或两个应用程序可能要求某些需要在应用程序中显示的数据可能已经被格式化为HTML,开发人员无法控制该内容可能只是这种情况。换句话说...相关问题。 (2认同)

Ali*_*eza 7

只需[innerHTML]在您的HTML 中使用属性,如下所示:

<div [innerHTML]="myVal"></div>
Run Code Online (Sandbox Code Playgroud)

您的组件中是否曾经有过包含一些 html 标记或需要在模板中显示的实体的属性?传统的插值将不起作用,但innerHTML 属性绑定来救援。

使用{{myVal}} 按预期工作!这不会拾取像<p>,<strong>等的 HTML 标签,并且仅将其作为字符串传递...

想象一下,您的组件中有以下代码:

const myVal:string ='<strong>Stackoverflow</strong> is <em>helpful!</em>'

如果您使用{{myVal}},您将在视图中看到:

<strong>Stackoverflow</strong> is <em>helpful!</em>
Run Code Online (Sandbox Code Playgroud)

但使用[innerHTML]="myVal"使结果如预期:

计算器有帮助的!


小智 5

 <div [innerHTML]="HtmlPrint"></div><br>
Run Code Online (Sandbox Code Playgroud)

innerHTML的是HTML的元素,它允许你设置它的HTML内容编程的特性。还有一个innerText 属性,它将内容定义为纯文本。

所述[attributeName]="value"框支架,围绕该属性定义的角输入结合。这意味着,属性的值(在您的情况下为innerHtml)绑定到给定的表达式,当表达式结果更改时,属性值也会更改。

所以基本上[innerHtml]允许您绑定和动态更改给定 HTML 元素的 html 内容。