Angular アプリケーションを作成していて、表示したい HTML 応答があります。
それ、どうやったら出来るの?単純にバインディング構文を使用すると、{{myVal}}
すべての HTML 文字がエンコードされます (もちろん)。
innerHTML
adiv
を変数値にバインドする必要があります。
Angular アプリケーションを作成していて、表示したい HTML 応答があります。
それ、どうやったら出来るの?単純にバインディング構文を使用すると、{{myVal}}
すべての HTML 文字がエンコードされます (もちろん)。
innerHTML
adiv
を変数値にバインドする必要があります。
Angular 2.0.0 および Angular 4.0.0 最終版
安全なコンテンツのために
<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 を信頼すると、セキュリティ上のリスクが生じる可能性があります。前述のドキュメントには次のように記載されています。
いずれかの API を呼び出すと、
bypassSecurityTrust...
渡された値に対する Angular の組み込みサニタイズが無効になります。この呼び出しに含まれるすべての値とコード パスを慎重にチェックして監査してください。このセキュリティ コンテキストでは、すべてのユーザー データが適切にエスケープされていることを確認してください。詳細については、セキュリティ ガイドを参照してください。
Angular マークアップ
何かのようなもの
class FooComponent {
bar = 'bar';
foo = `<div>{{bar}}</div>
<my-comp></my-comp>
<input [(ngModel)]="bar">`;
と
<div [innerHTML]="foo"></div>
では、Angular が Angular 固有のものを処理することはありませんfoo
。Angular は、ビルド時に Angular 固有のマークアップを生成されたコードに置き換えます。実行時に追加されたマークアップは、Angular によって処理されません。
Angular 固有のマークアップ (プロパティまたは値バインディング、コンポーネント、ディレクティブ、パイプなど) を含む HTML を追加するには、動的モジュールを追加し、実行時にコンポーネントをコンパイルする必要があります。この回答では、動的テンプレートを使用/作成して動的コンポーネントを Angular 2.0 でコンパイルするにはどうすればよいですか?
[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 スタイルも参照してください。
angular2@2.0.0-alpha.44:
を使用する場合、Html-Binding は機能しません{{interpolation}}
。代わりに「式」を使用してください。
無効
<p [innerHTML]="{{item.anleser}}"></p>
-> エラーをスローします (期待される式ではなく補間)
正しい
<p [innerHTML]="item.anleser"></p>
→これが正しいやり方です。
次のような要素を式に追加できます。
<p [innerHTML]="'<b>'+item.anleser+'</b>'"></p>
ヒント
[innerHTML]
を使用して追加された (または同様の方法で動的に追加された) HTMLelement.appenChild()
は、セキュリティ目的のサニタイズ以外の方法で Angular によって処理されることはありません。
このようなことは、HTML がコンポーネント テンプレートに静的に追加された場合にのみ機能します。これが必要な場合は、動的テンプレートを使用/作成して Angular 2.0 で動的コンポーネントをコンパイルするにはどうすればよいですか? で説明されているように、実行時にコンポーネントを作成できます。
最新の他の回答を参照してください。
これは私にとってはうまくいきます:<div innerHTML = "{{ myVal }}"></div>
(Angular2、Alpha 33)
別の SO: Inserting HTML from server from DOM into angular2 (Angular2 での一般的な DOM 操作) によると、「inner-html」は Angular 1.X の「ng-bind-html」と同等です。
完全な回答を得るために、HTML
コンテンツが にあるcomponent
variable
場合は、次を使用することもできます。
<div [innerHTML]=componentVariableThatHasTheHtml></div>
ここでポイントが抜けていたら申し訳ありませんが、別のアプローチをお勧めします。
サーバー側のアプリケーションから生データを返し、それをクライアント側のテンプレートにバインドする方が良いと思います。サーバーからjsonのみを返すため、これにより、より機敏なリクエストが可能になります。
私には、サーバーからhtmlを取得して「そのまま」DOMに挿入するだけの場合、Angularを使用する意味がないように思えます。
Angular 1.x に html バインディングがあることは知っていますが、Angular 2.0 に対応するものはまだ見たことがありません。ただし、後で追加する場合があります。とにかく、Angular 2.0 アプリ用のデータ API を引き続き検討します。
興味がある場合は、ここにいくつかの簡単なデータ バインディングのサンプルがあります: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples
短い答えはすでにここで提供されています:<div [innerHTML]="yourHtml">
バインディングを使用してください。
ただし、ここで言及されている残りのアドバイスは誤解を招く可能性があります。そのようなプロパティにバインドする場合、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 には適していません。したがって、CSS を処理するために Angular の 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 およびサーバー側の renedring 環境でも機能します。
次の 2 つの方法を使用できます。
<div [innerHTML]="myVal"></div>
また
<div innerHTML="{{myVal}}"></div>
HTML 形式のバインディングを再バインドするのに役立つ以下のライブラリをビルドしました。このライブラリを使用するには、以下の手順を参照してください。このライブラリは、基本的に AOT に JIT コンパイラ コードを挿入することを可能にします。
を使用してライブラリをインストールします
npm i angular-html-recompile
以下のコードを app.component.html ファイルに追加します
<pk-angular-html-recompile *ngIf="template !== ''"
[stringTemplate]="template"
[data]="dataObject">
</pk-angular-html-recompile>
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;
}
}
モジュールを 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 { }
このライブラリは、基本的な html、Angular マテリアル、フレックス レイアウトをサポートしています。この機能を使用するには、以下の依存関係をインストールします
npm i -s @angular/material @angular/flex-layout
Angular v2.1.1 での作業
<div [innerHTML]="variable or htmlString">
</div>