【问题标题】:Angular HTML binding角度 HTML 绑定
【发布时间】:2015-10-11 10:53:14
【问题描述】:

我正在编写一个 Angular 应用程序,并且我想要显示一个 HTML 响应。

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

我需要以某种方式将divinnerHTML 绑定到变量值。

【问题讨论】:

标签: angular angular2-template angular2-databinding


【解决方案1】:

为了得到一个完整的答案,如果您的 HTML 内容在 component variable 中,您也可以使用:

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

【讨论】:

    【解决方案2】:

    我已经构建了下面的库,这将有助于重新绑定 html 格式的绑定。 请找到以下步骤来使用这个库。这个库基本上允许在 AOT 中注入 JIT 编译器代码

    1. 使用安装库

      npm i angular-html-recompile
      
    2. 在 app.component.html 文件中添加以下代码

      <pk-angular-html-recompile *ngIf="template !== ''" 
                                 [stringTemplate]="template" 
                                 [data]="dataObject"> 
      </pk-angular-html-recompile>
      
    3. 在 app.component.ts 文件中使用以下代码

      import { Component, OnInit, ViewChild } from '@angular/core';
      import { AngularHtmlRecompileComponent, AngularHtmlRecompileService } from 'angular-html-recompile';
      
      @Component({
          selector: 'app-root',
          templateUrl: './app.component.html',
          styleUrls: ['./app.component.scss']
      })
      export class AppComponent implements OnInit {
      
          @ViewChild(AngularHtmlRecompileComponent, { static: true }) comp !: AngularHtmlRecompileComponent;
      
          constructor(
              private angularHtmlRecompileService: AngularHtmlRecompileService) {
          }
      
          public dataObject: any;
      
          public template = `<div class="login-wrapper" fxLayout="row" fxLayoutAlign="center center">
          <mat-card class="box">
              <mat-card-header>
              <mat-card-title>Register</mat-card-title>
              </mat-card-header>
              <form class="example-form">
              <mat-card-content>
                  <mat-form-field class="example-full-width">
                  <input matInput placeholder="Username" [value]="Username" (keydown)="onControlEvent($event,'Username')">
                  </mat-form-field>
                  <mat-form-field class="example-full-width">
                  <input matInput placeholder="Email" [value]="Email" (keydown)="onControlEvent($event,'Email')">
                  </mat-form-field>
                  <mat-form-field *ngIf="isShow" class="example-full-width">
                  <input matInput placeholder="Password" [value]="Password" (keydown)="onControlEvent($event,'Password')">
                  </mat-form-field>
                  <mat-form-field class="example-full-width">
                  <mat-label>Choose a role...</mat-label>
                  <mat-select (selectionChange)="onControlEvent($event, 'selectedValue')">
                      <mat-option [value]="roles" *ngFor="let roles of Roles">{{roles}}
                      </mat-option>
                  </mat-select>
                  </mat-form-field>
              </mat-card-content>
              <button mat-stroked-button color="accent" class="btn-block" (click)="buttomClickEvent('submit')" >Register</button>
              </form>
          </mat-card>
          </div>`;
      
          ngOnInit(): void {
      
              this.angularHtmlRecompileService.sharedData.subscribe((respose: any) => {
                  if (respose) {
                      switch (respose.key) {
                          case `Username`:
                              // Call any method on change of name
                              break;
                          case `Password`:
                              //Update password from main component
                              this.comp[`cmpRef`].instance['Password'] = "Karthik";
                              break;
                          case `submit`:
                              //Get reference of all parameters on submit click
                              //1. respose.data OR
                              //use this.comp[`cmpRef`].instance
                              break;
                          default:
                              break;
                      }
                  }
              });
      
              this.prepareData();
      
          }
      
          prepareData() {
      
              //Prepare data in following format only for easy binding
              //Template preparation and data preparation can be done once data received from service
      
              // AngularHtmlRecompileComponent will not be rendered until you pass data 
      
              this.dataObject = [
                  { key: 'Username', value: 'Pranay' },
                  { key: 'Email', value: 'abc@test.com', },
                  { key: 'Password', value: 'test123', },
                  { key: 'Roles', value: ['Admin', 'Author', 'Reader'] },
                  { key: 'isShow', value: this.updateView() }
              ];
      
          }
      
          updateView() {
              //Write down logic before rendering to UI to work ngIf directive
              return true;
          }
      }
      
    4. 将模块添加到 app.module.ts 文件中

      import { NgModule } from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';
      
      import { AppComponent } from './app.component';
      import { AngularHtmlRecompileModule } from "angular-html-recompile";
      
      @NgModule({
          declarations: [
              AppComponent
          ],
          imports: [
              BrowserModule,
              AngularHtmlRecompileModule
          ],
          providers: [],
          bootstrap: [AppComponent]
      })
      export class AppModule { }
      
    5. 这个库支持基本的 html、Angular 材质、flex 布局。 要使用此功能,请安装以下依赖项

      npm i -s @angular/material @angular/flex-layout
      

    【讨论】:

      【解决方案3】:

      Angular 2+ 支持将呈现 HTML 的 [innerHTML] 属性绑定。如果您要以其他方式使用插值,它将被视为字符串。

      进入.html文件

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

      进入.ts文件

      theHtmlString:String = "enter your html codes here";
      

      【讨论】:

        【解决方案4】:

        您可以使用以下两种方式。

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

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

        【讨论】:

          【解决方案5】:

          您还可以使用 DOM 属性绑定将 Angular 组件类属性与模板绑定。

          例如:&lt;div [innerHTML]="theHtmlString"&gt;&lt;/div&gt;

          使用如下规范形式:

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

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

          查看工作中的 stackblitz example here

          【讨论】:

            【解决方案6】:

            正确的语法如下:

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

            Documentation Reference

            【讨论】:

            • 有什么办法可以强制 angular 对该 innerHTML 的元素运行其绑定?我需要使用 ,并希望从外部 html 提供它。
            • @thouliha 我建议就您的问题开始一个新帖子。
            • 它在我的例子中呈现字符串,但对标记做了一些事情。似乎已经剥离了标记上的属性。我在 2.4.6
            • @thouliha 你找到答案了吗?有什么方法可以强制 Angular 在注射后重新评估绑定?我所有的绑定和模板都在 innerHtml 部分中被破坏了
            • 其他答案stackoverflow.com/a/41089093/1225421stackoverflow.com/a/41121006/1225421 解决了安全HTML sanitzer 问题。
            【解决方案7】:

            只是对迄今为止所有出色的答案发表一点补充:如果您正在使用 [innerHTML] 渲染 Angular 组件并且对它无法像我一样工作感到沮丧,请查看我编写的 ngx-dynamic-hooks 库来解决这个问题。

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

            看到它在行动in this Stackblitz

            【讨论】:

              【解决方案8】:

              在 Angular v2.1.1 中工作

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

              【讨论】:

              • 这会为我生成:&lt;div _ngcontent-luf-0=""&gt;&lt;/div&gt;div 为空。
              【解决方案9】:

              请参考其他更新的答案。

              这对我有用:&lt;div innerHTML = "{{ myVal }}"&gt;&lt;/div&gt;(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”

              【讨论】:

              • 使用 [property] 绑定语法而不是 {{interpolation}}
              • 也可以在我无法工作的项目中工作
              【解决方案10】:

               &lt;div [innerHTML]="HtmlPrint"&gt;&lt;/div&gt;&lt;br&gt;

              innerHtml 是 HTML-Elements 的一个属性,它允许您以编程方式设置它的 html 内容。还有一个 innerText 属性将内容定义为纯文本。

              属性周围的[attributeName]="value" 方括号定义了一个Angular 输入绑定。这意味着,属性的值(在您的情况下为 innerHtml)绑定到给定的表达式,当表达式结果发生变化时,属性值也会发生变化。

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

              【讨论】:

                【解决方案11】:

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

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

                您可能会听到有关“清理”您的内容的建议,方法是使用 DomSanitizer 使用 bypassSecurityTrustXXX 方法将内容标记为安全。也有人建议使用管道来执行此操作,并且该管道通常称为 safeHtml

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

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

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

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

                <div [innerHtml]="value | dompurify"></div>
                

                这里建议的管道的不同之处在于它确实通过 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 {}
                

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

                【讨论】:

                  【解决方案12】:

                  您可以在 .html 中为样式、链接和 HTML 应用多个管道

                  <div [innerHTML]="announcementContent | safeUrl| safeHtml">
                                      </div>
                  

                  在 .ts 管道中用于“URL”消毒剂

                  import { Component, Pipe, PipeTransform } from '@angular/core';
                  import { DomSanitizer } from '@angular/platform-browser';
                  
                  @Pipe({ name: 'safeUrl' })
                  export class SafeUrlPipe implements PipeTransform {
                      constructor(private sanitizer: DomSanitizer) {}
                      transform(url) {
                          return this.sanitizer.bypassSecurityTrustResourceUrl(url);
                      }
                  }
                  

                  “HTML”消毒剂管道

                  import { Component, Pipe, PipeTransform } from '@angular/core';
                  import { DomSanitizer } from '@angular/platform-browser';
                  
                  @Pipe({
                      name: 'safeHtml'
                  })
                  export class SafeHtmlPipe implements PipeTransform {
                      constructor(private sanitized: DomSanitizer) {}
                      transform(value) {
                          return this.sanitized.bypassSecurityTrustHtml(value);
                      }
                  }
                  

                  这将同时应用而不会干扰任何样式和链接点击事件

                  【讨论】:

                    【解决方案13】:

                    如果你想在 Angular 2 或 Angular 4 中使用它并且还想保留内联 CSS,那么你可以使用

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

                    【讨论】:

                    • 这给了我一个错误`Uncaught (in promise): Error: Template parse errors: The pipe 'keepHtml' could not be found`
                    • 从“@angular/core”导入{Pipe,PipeTransform};
                    【解决方案14】:

                    我们总是可以将 html 内容传递给 innerHTML 属性以呈现 html 动态内容,但动态 html 内容也可能被感染或恶意。因此,在将动态内容传递给 innerHTML 之前,我们应始终确保内容已被清理(使用 DOMSanitizer),以便我们能够逃脱所有恶意内容。

                    试试下面的管道:

                    import { Pipe, PipeTransform } from "@angular/core";
                    import { DomSanitizer } from "@angular/platform-browser";
                    
                    @Pipe({name: 'safeHtml'})
                    export class SafeHtmlPipe implements PipeTransform {
                        constructor(private sanitized: DomSanitizer) {
                        }
                        transform(value: string) {
                            return this.sanitized.bypassSecurityTrustHtml(value);
                        }
                    }
                    
                    Usage:
                    <div [innerHTML]="content | safeHtml"></div>
                    

                    【讨论】:

                      【解决方案15】:

                      您可以使用多种方法来实现解决方案。正如已批准的答案中所述,您可以使用:

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

                      根据你想要达到的目标,你也可以尝试其他的东西,比如javascript DOM(不推荐,DOM操作很慢):

                      演示文稿

                      <div id="test"></test>
                      

                      组件

                      var p = document.getElementsById("test");
                      p.outerHTML = myVal;
                      

                      Property Binding

                      Javascript DOM Outer HTML

                      【讨论】:

                      • 无论 DOM 操作是否比 Angular 慢,使用getElementsById 或任何其他选择方法都是不好的,因为它可能会捕获属于完全不同组件的元素,如果它们包含具有相同的 ID(或其他条件)。
                      • 此外,它完全在任何角度区域之外执行,因此不会拾取更改。
                      【解决方案16】:

                      在 angular2@2.0.0-alpha.44 上:

                      使用{{interpolation}} 时,HTML 绑定将不起作用,请改用“表达式”:

                      无效

                      <p [innerHTML]="{{item.anleser}}"></p>
                      

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

                      正确

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

                      ->这是正确的方法。

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

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

                      提示

                      使用[innerHTML] 添加的HTML(或通过element.appenChild() 或类似的其他方式动态添加)不会被Angular 以任何方式处理,除了出于安全目的的清理。
                      只有在将 HTML 静态添加到组件模板时,这些事情才会起作用。如果你需要这个,你可以像How can I use/create dynamic template to compile dynamic Component with Angular 2.0?中解释的那样在运行时创建一个组件

                      【讨论】:

                      • 第三个例子不起作用。表达式不求值。输出只是字符串......任何其他方式将trustedHTML与另一个标签元素结合起来?
                      【解决方案17】:

                      Angular 2.0.0 和 Angular 4.0.0 最终版

                      只是为了安全的内容

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

                      DOMSanitizer

                      潜在的不安全 HTML 需要使用 Angulars DOM sanitizer 显式标记为受信任的,因此不会删除内容中潜在的不安全部分

                      <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

                      安全警告

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

                      调用任何bypassSecurityTrust... API 都会禁用 Angular 对传入值的内置清理。仔细检查和审核进入此调用的所有值和代码路径。确保针对此安全上下文适当地转义了任何用户数据。更多详情,请参阅Security Guide

                      角度标记

                      类似

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

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

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

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

                      【讨论】:

                      • 这应该是答案。注意被注释掉的两行。它实际上是第二个处理 HTML。
                      • 一定要import { BrowserModule, DomSanitizer } from '@angular/platform-browser'
                      • 还有import { Pipe } from '@angular/core'
                      • 改用DomSanitizer
                      • 这个答案解决了HTML认为不安全产生的问题。我设法定义了文本颜色并添加了一个 youtubeiframe。您无法通过简单地设置 innerHTML 来实现这一点,就像其他答案中描述的那样。
                      【解决方案18】:

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

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

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

                      使用{{myVal}} 按预期工作!这不会选择像 &lt;p&gt;&lt;strong&gt; 等 HTML 标签,并仅将其作为字符串传递...

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

                      const myVal:string ='&lt;strong&gt;Stackoverflow&lt;/strong&gt; is &lt;em&gt;helpful!&lt;/em&gt;'

                      如果你使用{{myVal}},你会在视图中得到这个:

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

                      但使用[innerHTML]="myVal"会使结果符合预期:

                      Stackoverflow 很有帮助!

                      【讨论】:

                        【解决方案19】:

                        如果您的 Angular(或任何框架)应用程序中有模板,并且您通过 HTTP 请求/响应从后端返回 HTML 模板,则您正在混淆前端和后端之间的模板。

                        为什么不将模板内容留在前端(我建议这样做)或后端(非常不透明的 imo)?

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

                        当其他人不得不处理您的代码(或者甚至您自己在一段时间后重新输入自己的代码)时,这将得到回报!

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

                        哲学,男人:)

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

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

                        【讨论】:

                        • -2 票。哈。好的,我会投票给这个答案,只是因为很明显其他答案几乎相同。尽管此答案没有提供干净的解决方案,但它是答案,它使您处于思考状态,而不是复制粘贴某人的解决方案。____在我的情况下,我无法使用此解决方案,因为我在后端有返回代码的库我必须显示为内部 html。如果我必须从该库中移动所有内容,可能会花费我一两个星期的时间。有时是不可能的。但可能我只会移动客户端的样式,这可能会也可能不会解决我的问题。
                        【解决方案20】:

                        [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

                        【讨论】:

                        • 其他解决方案先将字符串保存到 html 属性,然后再加载 html。将大字符串保存到属性会导致浏览器冻结甚至崩溃。我的解决方案省略了这个“属性部分”
                        • 是的,否则我不会在这里添加我的答案
                        • [innerHtml] 删除 Html 中硬编码的样式。为了集成所见即所得的编辑器,我不得不使用此处列出的方法。
                        • 这对于生成将进入 HTML 电子邮件的内容非常有用,不幸的是,仍然需要内联样式。其他使用插值的方法删除了内联样式。
                        • 这个@ViewChild 可以为多个 div 工作吗?如果是,怎么做?
                        【解决方案21】:

                        如 Angular 2 文档中所述,向 DOM 动态添加元素的方法是使用 @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 dynamically add component to DOM demo上添加了一个完整的演示应用程序

                        【讨论】:

                          【解决方案22】:

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

                          • [property]="expression" -> 任何 html 属性都可以链接到一个
                            表达。在这种情况下,如果表达式更改属性将更新, 但这不起作用。
                          • (event)="expression" -> 当事件激活执行表达式时。
                          • [(ngModel)]="property" -> 将属性从 js(或 ts)绑定到 html。此属性的任何更新都会随处可见。

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

                          例如here

                          【讨论】:

                            【解决方案23】:

                            如果 [innerHTML] 包含用户创建的内容,则不能直接使用 [innerHTML] 而不使用 Angular 的 DOM sanitizer。 @GünterZöchbauer in 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>
                            

                            【讨论】:

                            • @ObasiObenyOj 如果是有限的情况,您仍然可以在不使用单独的指令的情况下执行此操作,constructor( private sanitizer: Sanitizer) {} 并将结果绑定到您需要的任何内容中,强烈不建议使用 ElementRef。
                            • 它是否适用于输入和文本区域元素?
                            【解决方案24】:

                            如果我在这里遗漏了重点,我深表歉意,但我想推荐一种不同的方法:

                            我认为最好从服务器端应用程序返回原始数据并将其绑定到客户端的模板。这使得请求更加灵活,因为您只从服务器返回 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 的用例。例如。从远程获取格式化的文章。
                            • 另一个经常被忽略的场景是保护模板中的业务逻辑,有时您不希望未经授权的用户看到您用于显示信息的逻辑,因此您宁愿在服务器上准备视图侧面
                            • 另外,显示 HTML 电子邮件,例如 - 公平点/问题!
                            • 如果您错过了重点(您自己也承认这一点),那么为什么要发布回复?显然,Angular 的重点是使用它的视图引擎来绑定和渲染数据。但考虑到可能使用 Angular 应用程序的应用程序不计其数,实际上可行的是,其中一两个应用程序可能需要一些需要在应用程序中显示的数据可能已经格式化为 HTML,并且可能恰好是开发人员无法控制该内容的情况。换句话说……相关问题。
                            猜你喜欢
                            • 1970-01-01
                            • 2014-12-25
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2019-03-31
                            • 2016-05-26
                            • 2018-10-31
                            相关资源
                            最近更新 更多