[Angular]変数のバインドで、htmlタグを埋め込む

カテゴリ: Angular

Angularではjsの変数をhtmlへバインドする時、変数にHTMLが入っている場合はHTMLタグが自動で取り除かれます。
これはセキュリティを考慮した振る舞いです。

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `{{scriptStr}}`,
})

export class AppComponent {
  scriptStr: string = "<div style='color:blue;'>hello</div>";
}

タグも含めてバインドする

この振る舞いを避けたい場合は、以下のように[innerHHTML]を利用すると良いです。
これで、html内にdivタグが埋め込まれますが、style等の属性は自動で削除されてしまいます。

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<div [innerHTML]="scriptStr"></div>`,
})

export class AppComponent {
  scriptStr: string = "<div style='color:blue;'>hello</div>";
}

タグも属性も含めてバインドする

sytleなどの属性も含めてhtmlに埋め込みたい場合は、sanitizer.bypassSecurityTrustHtml()メソッドを使用します。
下記のコードでは、scriptStrに入っているHTMLテキストに対して"TrustHtml(信頼できるデータ)"のマークがついたSafeHtmlオブジェクトを作成し、trustScriptStr変数にセットしています。

テンプレート側では、trustScriptStrを出力すればタグの属性も含めてhtmlに反映されます。

import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml} from '@angular/platform-browser';

@Component({
  selector: 'my-app',
  template: `<div [innerHTML]="trustScriptStr"></div>`,
})

export class AppComponent {
  scriptStr: string = "<div style='color:blue;'>hello</div>";
  trustScriptStr: SafeHtml;

  constructor(private sanitizer: DomSanitizer) {
    this.trustScriptStr = sanitizer.bypassSecurityTrustHtml(this.scriptStr);
  }
}

出力結果

上記の3パターンをまとめて実行してみた結果は下記の通りです。

import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml} from '@angular/platform-browser';

@Component({
  selector: 'my-app',
  template: `
  <hr />
  {{scriptStr}}
  <hr />
  <div [innerHTML]="scriptStr"></div>
  <hr />
  <div [innerHTML]="trustScriptStr"></div>
  `,
})

export class AppComponent {
  scriptStr: string = "<div style='color:blue;'>hello</div>";
  trustScriptStr: SafeHtml;

  constructor(private sanitizer: DomSanitizer) {
    this.trustScriptStr = sanitizer.bypassSecurityTrustHtml(this.scriptStr);
  }
}

こちらもおススメ

One thought on “[Angular]変数のバインドで、htmlタグを埋め込む

コメントを残す

メールアドレスが公開されることはありません。