首页 文章

Angular HTML绑定

提问于
浏览
543

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

我怎么做?如果我只使用绑定语法 {{myVal}} 它会编码所有 HTML 个字符(当然) .

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

14 回答

  • 15

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

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

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

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

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

  • 14

    正确的语法如下:

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

    7.0.2 工作

    Documentation Reference

  • -1

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

    根据另一个SO:Inserting HTML from server into DOM with angular2 (general DOM manipulation in Angular2),"inner-html"相当于Angular 1.X中的"ng-bind-html"

  • 202

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

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

    您的组件中是否包含某些属性,您需要在模板中显示某些html标记或实体?传统的插值不起作用,但innerHTML属性绑定可以解决问题 .

    按预期使用 {{myVal}} Does NOT 工作!这 won't 拿起像 <p><strong> 等HTML标签,并仅将其作为字符串传递...

    想象一下,你的组件中有这个代码:

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

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

    <strong>Stackoverflow</strong> is <em>helpful!</em>
    

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

    Stackoverflow 很有帮助!

  • 134

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

    <div [innerHTML]=componementVariableThatHasTheHtml></div>
    
  • 7

    Working in AngularJS v2.1.1

    <div [innerHTML]="variable or htmlString">
    </div>
    
  • 29

    Angular 2 中,您可以执行3种类型的绑定:

    • [property]="expression" - >任何html属性都可以链接到
      表达 . 在这种情况下,如果表达式更改属性将更新,但这不起作用 .

    • (event)="expression" - >事件激活执行表达式时 .

    • [(ngModel)]="property" - >将属性从js(或ts)绑定到html . 此属性的任何更新都会在任何地方都显而易见 .

    表达式可以是值,属性或方法 . 例如:'4','controller.var','getValue()'

    示例here

  • 936

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

    我想分享其他方法:

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

    <div #dataContainer></div>
    

    然后,在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;
        }
    }
    

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

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

    另见Angular 2 - innerHTML styling

  • -2

    在angular2@2.0.0-alpha.44上:

    使用 {{interpolation}} 时,Html-Binding将无效,请使用"Expression":

    invalid

    <p [innerHTML]="{{item.anleser}}"></p>
    
    • 抛出错误(插值而不是预期的表达式)

    correct

    <p [innerHTML]="item.anleser"></p>
    
    • 这是正确的方法 .

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

    <p [innerHTML]="'<b>'+item.anleser+'</b>'"></p>
    

    hint

    使用 [innerHTML] 添加的HTML(或通过其他方式动态添加,如 element.appenChild() 或类似名称)将不会由Angular以任何方式处理,除非为了安全目的而进行清理 .
    仅当HTML静态添加到组件模板时,此类操作才有效 . 如果需要,可以在运行时创建组件,如How can I use/create dynamic template to compile dynamic Component with Angular 2.0?中所述

  • 1

    Angular 2.0.0 and Angular 4.0.0 final

    仅为了安全的内容

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

    DOMSanitizer

    潜在的不安全HTML需要使用Angulars 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
      }
    }
    

    另见In RC.1 some styles can't be added using binding syntax

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

    Security warning

    信任用户添加的HTML可能会带来安全风险 . 之前mentioned docs州:

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

    Angular markup

    就像是

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

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

    won't cause Angular to process anything Angular-specific in foo . Angular使用生成的代码替换构建时的Angular特定标记 . 标记在运行时添加 won't be processed by Angular .

    添加包含Angular特定标记的HTML(属性或值绑定,组件,指令,管道......)需要在运行时添加动态模块并编译组件 . 这个答案提供了更多细节How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

  • 9

    如果它包含用户创建的内容,则不使用Angular的DOM清理程序直接使用[innerHTML] . @GünterZöchbauerin his answer建议的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);
        }
      }
    }
    

    要使用的

    <div [safeHtml]="myVal"></div>
    
  • 0

    如Angular 2 doc所述,向DOM动态添加元素的方法是使用@ Angular / core中的ViewContainerRef类 .

    您需要做的是声明一个指令,该指令将实现ViewContainerRef并在DOM上扮演占位符 .

    Directive

    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 dynamically add component to DOM demo上添加了一个完全可用的演示应用程序

  • -1

    如果您的角度(或任何框架)应用程序中有模板,并且您通过HTTP请求/响应从后端返回HTML模板,那么您将在前端和后端之间混合模板 .

    为什么不把模板化的东西留在前端(我会建议),或者在后端(非常不透明的imo)?

    如果你在前端保留模板,为什么不用JSON响应对后端的请求 . 您甚至不必实现RESTful结构,但在一侧保留模板可使您的代码更加透明 .

    当其他人必须处理您的代码时(或者您自己在一段时间后重新输入自己的代码),这将收回!

    如果你做得对,你会得到带有小模板的小组件,最重要的是,如果你的代码是imba,那些不懂编码语言的人将能够理解你的模板和你的逻辑!另外,尽可能保持您的功能/方法尽可能小 . 您最终会发现,与大型函数/方法/类相比,维护,重构,查看和添加功能将更容易,并且在前端和后端之间混合模板和逻辑 - 并在后端保留尽可能多的逻辑如果你的前端需要更灵活(例如编写一个android前端或切换到不同的前端框架) .

    哲学,男人:)

    ps:你不必实现100%干净的代码,因为它非常昂贵 - 特别是如果你必须激励团队成员;)但是:你应该在清洁代码的方法和你拥有的代码之间找到一个很好的 balancer (也许它已经很干净了)

    如果可以的话,检查书,让它进入你的灵魂:https://de.wikipedia.org/wiki/Clean_Code

  • 0

    以下代码将帮助您

    myval你可以用所需的html替换

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

相关问题