Gaya sudut 2 - gaya dalamHTML

170

Saya mendapatkan potongan kode HTML dari panggilan HTTP. Saya meletakkan blok HTML dalam sebuah variabel dan menyisipkannya di halaman saya dengan [innerHTML] tetapi saya tidak bisa mendesain blok HTML yang dimasukkan. Adakah yang punya saran bagaimana saya bisa mencapai ini?

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

HTML yang ingin saya gaya adalah blok yang terdapat dalam variabel "kalender".

Jakob Svenningsson
sumber
Gaya dari mana? Dari dalam komponen atau dari gaya yang ditambahkan index.html?
Günter Zöchbauer
apa yang Anda maksud dengan can not style the inserted HTML block? Tunjukkan pada kami apa yang telah dilakukan untuk itu dengan potongan kode kecil.
micronyks
Saya telah memperbarui posting saya dengan cuplikan kode! :) terima kasih
Jakob Svenningsson
1
Saya menambahkan tautan Plunker ke jawaban saya
Günter Zöchbauer
@ GünterZöchbauer bagaimana jika kode HTML memiliki inline css? bagaimana itu akan diberikan?
iniravpatel

Jawaban:

320

pembaruan 2 ::slotted

::slotted sekarang didukung oleh semua browser baru dan dapat digunakan dengan ViewEncapsulation.ShadowDom

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

perbarui 1 :: ng-sedalam

/deep/sudah usang dan diganti dengan ::ng-deep.

::ng-deep juga sudah ditandai usang, tetapi belum ada pengganti yang tersedia.

Ketika ViewEncapsulation.Nativedidukung dengan baik oleh semua browser dan mendukung penataan batas bayangan DOM, ::ng-deepmungkin akan dihentikan.

asli

Angular menambahkan semua jenis kelas CSS ke HTML yang ditambahkannya ke DOM untuk meniru bayangan DOM CSS enkapsulasi untuk mencegah gaya pendarahan masuk dan keluar dari komponen. Angular juga menulis ulang CSS yang Anda tambahkan agar sesuai dengan kelas yang ditambahkan ini. Untuk HTML ditambahkan menggunakan [innerHTML]kelas-kelas ini tidak ditambahkan dan CSS yang ditulis ulang tidak cocok.

Sebagai solusinya coba

  • untuk CSS ditambahkan ke komponen
/* :host /deep/ mySelector { */
:host ::ng-deep mySelector { 
  background-color: blue;
}
  • untuk CSS ditambahkan ke index.html
/* body /deep/ mySelector { */
body ::ng-deep mySelector {
  background-color: green;
}

>>>(dan yang setara /deep/tetapi /deep/bekerja lebih baik dengan SASS) dan ::shadowditambahkan dalam 2.0.0-beta.10. Mereka mirip dengan penggabung bayangan DOM CSS (yang sudah usang) dan hanya berfungsi dengan encapsulation: ViewEncapsulation.Emulatedyang merupakan default di Angular2. Mereka mungkin juga bekerja samaViewEncapsulation.None tetapi kemudian hanya diabaikan karena mereka tidak perlu. Combinator ini hanya solusi perantara sampai fitur yang lebih canggih untuk penataan komponen silang didukung.

Pendekatan lain adalah menggunakan

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

untuk semua komponen yang memblokir CSS Anda (tergantung pada tempat Anda menambahkan CSS dan di mana HTML ingin Anda gaya - mungkin semua komponen dalam aplikasi Anda)

Memperbarui

Contoh Plunker

Günter Zöchbauer
sumber
6
Hanya catatan untuk siapa pun, ini tidak berfungsi dengan node-sass, atau dengan styleUrl. Hanya dalam gaya: [...]
thouliha
12
Dengan penggunaan SASS dan /deep/bukannya>>>
Günter Zöchbauer
1
Anda tidak dapat memiliki arahan atau komponen dalam konten yang ditambahkan denganinneeHTML
Günter Zöchbauer
1
Jika HTML yang disediakan oleh panggilan HTTP besar dan memiliki inline css bagaimana itu mungkin karena saya tidak memiliki gaya yang telah ditentukan, saya mendapatkannya hanya dari inline css @ GünterZöchbauer
iniravpatel
1
Menyimpan hari di Angular 8! Terima kasih. Sulit untuk menjawab pertanyaan dengan benar untuk menemukan jawaban ini!
Pianoman
12

Solusi sederhana yang perlu Anda ikuti adalah

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

constructor(private sanitizer: DomSanitizer){}

transformYourHtml(htmlTextWithStyle) {
    return this.sanitizer.bypassSecurityTrustHtml(htmlTextWithStyle);
}
Sahil Ralkar
sumber
2

Jika Anda mencoba menata elemen HTML yang ditambahkan secara dinamis di dalam komponen Angular, ini mungkin berguna:

// 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(), '')
}

Dugaan saya adalah bahwa konvensi untuk atribut ini tidak dijamin stabil di antara versi Angular, sehingga orang mungkin akan mengalami masalah dengan solusi ini ketika meningkatkan ke versi baru Angular (walaupun, memperbarui solusi ini kemungkinan akan sepele karena kasus).

Trevor
sumber
2

Kami sering menarik konten dari CMS kami sebagai [innerHTML]="content.title". Kami menempatkan kelas yang diperlukan di styles.scssfile root aplikasi daripada di file scss komponen. CMS kami dengan sengaja menghapus gaya in-line sehingga kami harus menyiapkan kelas yang dapat digunakan penulis dalam konten mereka. Ingat menggunakan {{content.title}}dalam template tidak akan membuat html dari konten.

Lyfo
sumber
-3

Jika Anda menggunakan sass sebagai preprocessor gaya, Anda dapat kembali ke kompiler Sass asli untuk dependensi dev dengan:

npm install node-sass --save-dev

Sehingga Anda bisa tetap menggunakan / mendalam / untuk pengembangan.

Brian Lu
sumber