Dalam pekerjaan sehari-hari, ketika kita mendefinisikan Component , kita harus mempertimbangkan enkapsulasinya , yaitu, apakah Anda mengharapkan gaya yang ditentukan dalam komponen ini hanya bekerja pada komponen ini, atau Anda ingin gaya tersebut bertindak secara global. Di Angular, gaya komponen dapat dienkapsulasi dalam elemen host komponen sehingga tidak memengaruhi aplikasi lainnya. Dekorator Komponen menyediakan opsi enkapsulasi yang dapat digunakan untuk mengontrol bagaimana enkapsulasi tampilan diterapkan per komponen. [Rekomendasi tutorial terkait: "tutorial sudut"]
Ada tiga mode enkapsulasi di Angular, yaitu ViewEncapsulation.ShadowDom, ViewEncapsulation.Emulated, dan ViewEncapsulation.None.
ekspor enum LihatEnkapsulasi { /** * Mengemulasi perilaku enkapsulasi Shadow DOM asli dengan menambahkan atribut tertentu ke * elemen host komponen dan menerapkan atribut yang sama ke semua pemilih CSS yang disediakan * melalui {@link Component#styles style} atau {@link Component#styleUrls styleUrls}. * * Ini adalah opsi default. */ Ditiru = 0, /** * Tidak menyediakan enkapsulasi gaya CSS apa pun, artinya semua gaya disediakan * melalui {@link Component#styles style} atau {@link Component#styleUrls styleUrls} berlaku * ke elemen HTML apa pun pada aplikasi apa pun Komponen hostnya. */ Tidak ada = 2, /** * Menggunakan API Shadow DOM asli browser untuk merangkum gaya CSS, artinya ia menciptakannya * ShadowRoot untuk elemen host komponen yang kemudian digunakan untuk merangkum * semua gaya Komponen. */ BayanganDom=3 }
Jika tidak disediakan, nilai diperoleh dari CompilerOptions. Opsi kompiler default adalah ViewEncapsulation.Emulated.
Jika kebijakan disetel ke ViewEncapsulation.Emulated dan komponen tidak menentukan gaya atau styleUrls, maka secara otomatis akan beralih ke ViewEncapsulation.None.
Tahukah Anda mengapa tidak ada 1 di tipe enumerasi ? Lebih lanjut tentang ini nanti.
Kesampingkan enkapsulasi ShadowDom di Angular, pertama-tama mari kita lihat apa itu ShadowDOM.
Shadow DOM memungkinkan pohon DOM tersembunyi untuk dilampirkan ke pohon DOM biasa - dimulai dengan simpul akar bayangan. Di bawah simpul akar ini, dapat berupa elemen apa saja, sama seperti elemen DOM biasa.
Di sini, ada beberapa istilah khusus Shadow DOM yang perlu kita pahami:
Anda dapat memanipulasi Shadow DOM dengan cara yang sama seperti DOM biasa - seperti menambahkan node anak, mengatur properti, dan menambahkan gaya Anda sendiri ke node (misalnya, melalui properti element.style), atau menambahkan gaya ke keseluruhan Shadow DOM (misalnya menambahkan gaya di dalam elemen). Perbedaannya adalah elemen di dalam Shadow DOM tidak akan pernah memengaruhi elemen di luarnya (kecuali :fokus-dalam), yang memfasilitasi enkapsulasi.
Mari kita lihat contoh sederhana.
<!DOCTYPEhtml> <html> <kepala> <meta charset="UTF-8"> <meta http-equiv="Kompatibel dengan X-UA" content="IE=Edge"> <meta name="viewport" content="width=lebar perangkat, skala awal=1.0"> <title>DOM Bayangan</title> <gaya> menjangkau{ warna: hijau; } </gaya> </kepala> <tubuh> <span>Saya Root</span> <div id="aplikasi"></div> <skrip> biarkan aplikasi = document.querySelector('#app'); biarkan shadow1 = app.attachShadow({ mode: 'open'}); biarkan style1 = document.createElement('style'); style1.appendChild(document.createTextNode("span{color: merah;}")); shadow1.appendChild(style1); biarkan span1 = document.createElement('span'); span1.textContent = 'Saya span.'; shadow1.appendChild(span1); </skrip> </tubuh> </html>
Contoh di atas mendefinisikan gaya span global dan gaya span di shadowDOM. Terlihat bahwa keduanya tidak terpengaruh satu sama lain.
Setelah memahami apa itu ShadowDOM, mari kita lihat enkapsulasi ShadowDOM di Angular.
Angular menggunakan Shadow DOM API bawaan browser untuk membungkus tampilan komponen dalam ShadowRoot (yang berfungsi sebagai elemen host komponen) dan menerapkan gaya yang disediakan secara terisolasi. ViewEncapsulation.ShadowDom hanya berfungsi di browser dengan dukungan bawaan untuk shadow DOM. Tidak semua browser mendukungnya, itulah sebabnya ViewEncapsulation.Emulated adalah mode yang direkomendasikan dan default.
Misalnya, dalam contoh berikut, gunakan ViewEncapsulation.ShadowDom .
@Komponen({ pemilih: 'anak-pengguna', templateUrl: 'UserChild.component.html', gaya: [` h3{ warna: merah; } `], enkapsulasi: ViewEncapsulation.ShadowDom }) kelas ekspor UserChildComponent mengimplementasikan OnInit { ... }
Dari halaman berjalan, kita dapat melihat bahwa komponen anak-pengguna dienkapsulasi secara internal ke dalam ShadowDOM, dan gaya juga dienkapsulasi di dalamnya, yang tidak akan memengaruhi gaya eksternal.
Angular memodifikasi pemilih CSS komponen sehingga hanya berlaku pada tampilan komponen dan tidak memengaruhi elemen lain dalam aplikasi (meniru perilaku Shadow DOM).
Saat menggunakan enkapsulasi tampilan tiruan, Angular memproses semua gaya komponen terlebih dahulu sehingga hanya berlaku pada tampilan komponen. Dalam DOM aplikasi Angular yang sedang berjalan, elemen yang berisi komponen menggunakan pola enkapsulasi tampilan tiruan memiliki beberapa atribut tambahan yang dilampirkan:
<hero-details _nghost-pmm-5> <h3 _ngcontent-pmm-5>Tuan Fantastis</h3> <tim pahlawan _ngcontent-pmm-5 _nghost-pmm-6> <h4 _ngcontent-pmm-6>Tim</h4> </tim pahlawan> </hero-details>
Ada dua atribut seperti itu:
Atribut | detail_nghost |
---|---|
ditambahkan | ke elemen yang membungkus komponen view , yang akan menjadi ShadowRoots dalam pembungkus Shadow DOM asli. Hal ini biasanya terjadi pada elemen host komponen . |
_ngcontent | ditambahkan ke elemen anak dalam tampilan komponen , dan atribut ini digunakan untuk mencocokkan elemen dengan ShadowRoots yang disimulasikan masing-masing (elemen host dengan atribut _nghost yang cocok). |
Nilai pasti dari properti ini adalah detail implementasi pribadi Angular. Mereka dibuat secara otomatis dan Anda tidak boleh mereferensikannya dalam kode aplikasi Anda.
Mereka menargetkan gaya komponen yang dihasilkan, yang dimasukkan ke bagian DOM:
[_nghost-pmm-5] { tampilan: blok; batas: 1 piksel hitam pekat; } h4[_ngcontent-pmm-6] { warna latar belakang: putih; batas: 1 piksel padat #777; }
Gaya ini pasca-pemrosesan sehingga setiap pemilih CSS ditambah dengan atribut _nghost atau _ngcontent yang sesuai. Selector yang dimodifikasi ini memastikan bahwa gaya diterapkan pada tampilan komponen dengan cara yang terisolasi dan tertarget.
<p>pekerjaan anak!</p>
p{ warna: hijau; }
@Komponen({ pemilih: 'aplikasi-anak', templateUrl: './child.component.html', styleUrls: ['./child.component.scss'], enkapsulasi: ViewEncapsulation.Emulated }) kelas ekspor ChildComponent mengimplementasikan OnInit { ... }
Hasil dari setting ViewEncapsulation.Emulated adalah tidak adanya Shadow DOM, namun komponen dienkapsulasi melalui mekanisme pengemasan gaya yang disediakan oleh Angular, sehingga gaya komponen tidak terpengaruh oleh pengaruh luar. Meskipun gaya tersebut masih diterapkan ke seluruh dokumen, Angular membuat pemilih [_ngcontent-oow-c11] untuk p. Terlihat bahwa gaya yang kita definisikan untuk komponen telah dimodifikasi oleh Angular. Sederhananya, meskipun ini adalah gaya global, ini tidak akan mempengaruhi gaya komponen lain karena adanya pemilih otomatis. Jika Anda menambahkan atribut ini secara manual ke elemen lain, gaya juga akan diterapkan ke elemen ini.
Angular tidak menerapkan segala bentuk enkapsulasi tampilan, yang berarti gaya apa pun yang ditentukan untuk komponen sebenarnya diterapkan secara global dan dapat memengaruhi elemen HTML apa pun yang ada dalam aplikasi. Pola ini pada dasarnya sama dengan memasukkan gaya ke dalam HTML itu sendiri.
orang tua:
<p #caption>orang tua bekerja!{{count}}</p> <p #caption>Yang pertama: {{count}}</p> <span class="red-font">induk</span> <app-child></app-child>
anak:
<div style="border: 1px solid green;"> <p>pekerjaan anak!</p> <span class="red-font">Anak</span> </div>
hal{ warna: hijau; } .font merah { warna: merah; }
@Komponen({ pemilih: 'aplikasi-anak', templateUrl: './child.component.html', styleUrls: ['./child.component.scss'], enkapsulasi: ViewEncapsulation.None }) kelas ekspor ChildComponent mengimplementasikan OnInit { ... }
ViewEncapsulation.Native tidak digunakan lagi di Angular2.
@Komponen({ ..., enkapsulasi: ViewEncapsulation.Native }) kelas ekspor Komponen Pengguna {
Pengaturan ViewEncapsulation.Native menghasilkan penggunaan fitur Shadow DOM asli. Angular akan merender komponen sesuai dengan format Shadow DOM yang didukung oleh browser. Sebenarnya, ini adalah ViewEncapsulation.ShadowDom yang lebih baru.
kami telah memperkenalkan tiga metode enkapsulasi tampilan sudut dan karakteristiknya masing-masing. Dalam pekerjaan sehari-hari, Anda harus memilih metode enkapsulasi mana yang sesuai dengan skenario tertentu.