web-dev-qa-db-ja.com

Angular HTMLバインディング

私はAngularアプリケーションを書いていて、表示したいHTMLレスポンスがあります。

それ、どうやったら出来るの?私が単にバインディング構文{{myVal}}を使うのであれば、それはすべてのHTML文字をエンコードします(もちろん)。

どういうわけかdivの内側のhtmlを変数値に束縛する必要があります。

640
Aviad P.

正しい構文は次のとおりです。

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

7.2.13で動作します

ドキュメントリファレンス

1074
prolink007

Angular 2.0.0および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
  }
}

RC.1では、一部のスタイルはバインディング構文を使用して追加できない も参照してください。

そしてドキュメント: https://angular.io/api/platform-b​​rowser/DomSanitizer

セキュリティ警告

ユーザーが追加したHTMLを信頼すると、セキュリティ上のリスクが生じる可能性があります。 before 前述のドキュメント 状態:

bypassSecurityTrust... AP​​Iのいずれかを呼び出すと、渡された値に対するAngularのビルトインサニタイズが無効になります。この呼び出しに入るすべての値とコードパスを慎重に確認および監査してください。このセキュリティコンテキストのユーザーデータが適切にエスケープされていることを確認してください。詳細については、 セキュリティガイド を参照してください。

角度マークアップ

何かのようなもの

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を追加するには、動的モジュールを追加し、実行時にコンポーネントをコンパイルする必要があります。この回答には、詳細が記載されています 動的テンプレートを使用/作成して、Angular 2.0で動的コンポーネントをコンパイルするにはどうすればよいですか?

275

ほとんどの場合、[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;
    }
}

それからhtml要素にテキストを追加するためにloadData関数を使うだけです。

それはあなたがネイティブのJavaScriptを使ってそれをするのと同じ方法ですが、Angular環境の中で。私はそれをお勧めしません、なぜならコードをより面倒にするからですが、時々他の選択肢がない。

Angular 2 - innerHTMLスタイリング も参照してください。

151
Piotrek

[email protected]上で:

{{interpolation}}を使用している場合、HTMLバインディングは機能しません。代わりに "Expression"を使用してください。

無効

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

- >エラーをスローします(予想される式ではなく補間)

正しい

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

- >これが正しい方法です。

次のように式に要素を追加することができます。

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

ヒント

[innerHTML]を使用して追加された(またはelement.appenChild()などのような他の方法で動的に追加された)HTMLは、セキュリティを目的としたサニタイズを除いて、Angularによって処理されません。
このようなことは、HTMLがコンポーネントテンプレートに静的に追加されている場合にのみ機能します。これが必要な場合は、 で説明しているように実行時にコンポーネントを作成できます。Angular 2.0を使用して動的コンポーネントをコンパイルするための動的テンプレートの使用方法は?

37
jvoigt

AngularのDOMサニタイザーを使用せずに[innerHTML]を直接使用することは、ユーザー作成のコンテンツが含まれている場合には選択できません。 @GünterZöchbauer 彼の答えの中で によって提案されたsafeHtmlパイプは、コンテンツをサニタイズする1つの方法です。次のディレクティブは別のものです。

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>
21
Rene Hamburger

これは私のために働く:<div innerHTML = "{{ myVal }}"></div>(Angular2、Alpha 33)

別の回答によると: angle2を使ってサーバーからDOMにHTMLを挿入する(Angular2での一般的なDOM操作) 、 "inner-html"はAngular 1の "ng-bind-html"と同等バツ

17
Fan Li

HTMLコンテンツがコンポーネント変数に含まれている場合は、完全な答えを得るためだけに使用することもできます。

<div [innerHTML]=componementVariableThatHasTheHtml></div>
10
Serj Sagan

私はここにポイントを逃しているならば謝罪します、しかし私は異なるアプローチを推薦したいです:

サーバー側のアプリケーションから生データを返し、それをクライアント側のテンプレートにバインドする方が良いと思います。サーバーからjsonが返されるだけなので、これはより機敏な要求になります。

私がしていることは、サーバーからHTMLを取得して「そのまま」DOMに注入するだけであれば、Angularを使用しても意味がないようです。

Angular 1.xにhtmlバインディングがあることは知っていますが、Angular 2.0にはまだ対応するものがありません。彼らは後でそれを追加するかもしれません。とにかく、私はまだあなたのAngular 2.0アプリのデータAPIを検討するでしょう。

あなたが興味を持っているなら、私はここにいくつかの簡単なデータ結合でここにいくつかのサンプルを持っています: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

8
TGH

HTML[innerHTML]属性を使用するだけで、次のようになります。

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

テンプレートに表示する必要があるHTMLマークアップまたはエンティティを含むコンポーネントのプロパティがありましたか?従来の補間は機能しませんが、innerHTMLプロパティバインディングが役に立ちます。

{{myVal}}の使用しない期待どおりに動作します!このしません<p><strong>などのHTMLタグを選択し、文字列としてのみ渡します...

コンポーネントに次のコードがあると想像してください。

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

{{myVal}}を使用すると、ビューでこれを取得できます。

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

ただし、[innerHTML]="myVal"を使用すると、次のように結果が期待どおりになります。

Stackoverflow ishelp!

4
Alireza

AngularJS v2.1.1での作業

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

あなたがそれをAngular 2またはAngular 4にして、インラインCSSを使い続けたいのなら、あなたは使うことができます。

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

HTMLの動的コンテンツをレンダリングするために、HTMLのコンテンツをinnerHTMLプロパティに渡すことができますが、その動的な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>
0
Suneet Bansal

Angular 2 では、3種類のバインディングを実行できます。

  • [property]="expression" - >どのhtmlプロパティも
    式この場合、式を変更するとプロパティが更新されますが、これは反対の方法では機能しません。
  • (event)="expression" - >イベント起動時に式を実行する.
  • [(ngModel)]="property" - >プロパティをjs(またはts)からhtmlにバインドします。この施設の更新はどこでも目立つでしょう。

式は値、属性、またはメソッドにすることができます。例えば、 '4'、 'controller.var'、 'getValue()'です。

ここ

0
adrisons

Angular 2 docで説明されているように、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に完全に機能するデモアプリケーションを追加しました。動的にDOMデモにコンポーネントを追加します

0
BogdanC

この方法を使用できます

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

またはIDでバインドします

 <div #html></div>

およびコンポーネント内

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;
    }
}
0

いくつかのアプローチを使用して、ソリューションを実現できます。承認済みの回答で既に述べたように、次を使用できます。

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

あなたが達成しようとしているものに応じて、javascript DOMのような他のものを試すこともできます(推奨されません、DOM操作は遅いです):

プレゼンテーション

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

コンポーネント

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

プロパティのバインド

Javascript DOM外部HTML

0
João Beirão