Angular 2-innerHTMLスタイル


170

HTTP呼び出しからHTMLコードのチャンクを取得しています。HTMLブロックを変数に入れ、[innerHTML]を使用してページに挿入しましたが、挿入したHTMLブロックのスタイルを設定できません。誰かがこれをどのように達成するかについて何か提案はありますか?

@Component({selector: 'calendar',
template: '<div [innerHTML]="calendar"></div>',
providers:[HomeService], 
styles: [` 
h3 {color:red;}
`})

スタイルを設定したいHTMLは、変数 "calendar"に含まれているブロックです。


スタイルはどこから?コンポーネント内から、またはindex.html?に追加されたスタイルから
ギュンターZöchbauer

どういう意味can not style the inserted HTML block?小さなコードスニペットを使用して、何が行われたかを示します。
micronyks 2016年

投稿をコードスニペットで更新しました。:)ありがとう
Jakob Svenningsson 2016年

1
私は私の答えにPlunkerリンクを追加
ギュンターZöchbauer

@GünterZöchbauerHTMLコードにインラインCSSがある場合はどうなりますか?どのようにレンダリングされますか?
iniravpatel 2017年

回答:


320

アップデート2 ::slotted

::slotted すべての新しいブラウザでサポートされるようになり、 ViewEncapsulation.ShadowDom

https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

アップデート1 :: ng-deep

/deep/は廃止され、に置き換えられました::ng-deep

::ng-deep もすでに非推奨とマークされていますが、まだ代替品はありません。

ときにViewEncapsulation.Native適切にすべてのブラウザとaccrossシャドウDOMの境界をスタイリング支持体によって支持されており、::ng-deepおそらく廃止されます。

元の

Angularは、あらゆる種類のCSSクラスをDOMに追加するHTMLに追加して、シャドウDOM CSSカプセル化をエミュレートして、コンポーネントの内外へのスタイルのブリードを防止します。Angularは、追加したCSSを書き換えて、これらの追加クラスに一致させます。[innerHTML]これらのクラスを使用して追加されたHTMLは追加されず、書き換えられたCSSは一致しません。

回避策として

  • コンポーネントに追加されたCSS
/* :host /deep/ mySelector { */
:host ::ng-deep mySelector { 
  background-color: blue;
}
  • に追加されたCSS index.html
/* body /deep/ mySelector { */
body ::ng-deep mySelector {
  background-color: green;
}

>>>(および同等のものです/deep//deep/、SASSでより適切に動作します)および::shadow2.0.0-beta.10で追加されました。これらはシャドウDOM CSSコンビencapsulation: ViewEncapsulation.Emulatedネーター(非推奨)に似ており、Angular2のデフォルトであるでのみ機能します。これらもおそらく動作しViewEncapsulation.Noneますが、必要がないため無視されます。これらのコンビネータは、クロスコンポーネントスタイリングのより高度な機能がサポートされるまでの中間的なソリューションにすぎません。

別のアプローチは使用することです

@Component({
  ...
  encapsulation: ViewEncapsulation.None,
})

CSSをブロックするすべてのコンポーネント(CSSを追加する場所と、HTMLがスタイルを設定する場所によって異なります。アプリケーションのすべてのコンポーネントである可能性があります)

更新

プランカーの例


6
だれでも注意してください。これはnode-sassでもstyleUrlでも機能しません。スタイルのみ:[...]
thouliha

12
SASSの使用により/deep/代わりに>>>
ギュンターZöchbauer

1
あなたが追加したコンテンツ内のディレクティブまたはcompinentsを持ってcan'rinneeHTML
ギュンターZöchbauer

1
HTMLは、HTTPによる通話が大であり、それは私がスタイルがあらかじめ定義持っていけないとどのようにそれが可能になりますインラインCSSを持って、私は唯一のGünterZöchbauer@インラインCSSからそれを取得しています提供されている場合
iniravpatel

1
Angular 8でその日を救った!ありがとう。この答えを見つけるために質問を正しく理解するのは難しいです!
ピアノマン

12

あなたが従う必要がある簡単な解決策は

import { DomSanitizer } from '@angular/platform-browser';

constructor(private sanitizer: DomSanitizer){}

transformYourHtml(htmlTextWithStyle) {
    return this.sanitizer.bypassSecurityTrustHtml(htmlTextWithStyle);
}

2

Angularコンポーネント内で動的に追加されたHTML要素のスタイルを設定しようとしている場合、これが役立つ場合があります。

// inside component class...

constructor(private hostRef: ElementRef) { }

getContentAttr(): string {
  const attrs = this.hostRef.nativeElement.attributes
  for (let i = 0, l = attrs.length; i < l; i++) {
    if (attrs[i].name.startsWith('_nghost-c')) {
      return `_ngcontent-c${attrs[i].name.substring(9)}`
    }
  }
}

ngAfterViewInit() {
  // dynamically add HTML element
  dynamicallyAddedHtmlElement.setAttribute(this.getContentAttr(), '')
}

私の推測では、この属性の規則はAngularのバージョン間で安定しているとは限らないため、Angularの新しいバージョンにアップグレードするときにこのソリューションで問題が発生する可能性があります(ただし、このソリューションを更新することは簡単です)場合)。


2

コンテンツはCMSから頻繁に取得され[innerHTML]="content.title"ます。必要なクラスstyles.scssは、コンポーネントのscssファイルではなく、アプリケーションのルートファイルに配置します。CMSは意図的にインラインスタイルを取り除いているため、作成者がコンテンツで使用できるクラスを準備しておく必要があります。{{content.title}}テンプレートで使用しても、コンテンツからhtmlがレンダリングされないことに注意してください。


-3

スタイルプリプロセッサとしてsassを使用している場合は、次の方法で、dev依存関係のネイティブSassコンパイラに切り替えることができます。

npm install node-sass --save-dev

開発のために/ deep /を使い続けることができるように。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.