Bagaimana cara mengatur ViewEncapsulation secara dinamis untuk Komponen Web?

Saya mencoba menginisialisasi komponen dengan atau tanpa Shadow DOM berdasarkan browser (karena IE tidak mendukung Shadow DOM).

Saya memeriksa apakah itu IE11 dan mengatur enkapsulasi ke Emulated untuk IE dan ShadowDom untuk browser lain.

const agent = window.navigator.userAgent;
const isIe11 = agent.indexOf('MSIE') === -1 && agent.indexOf('Trident') > 0;

@Component({
   selector: 'my-web-component',
   templateUrl: '...html',
   styleUrls: ['...scss'],
   encapsulation: isIe11 ? ViewEncapsulation.Emulated : ViewEncapsulation.ShadowDom
})
export class NavbarComponent implements OnInit { ... }

Nilai isIe11 benar sesuai dengan nilai kembalian pemeriksaan browser tetapi enkapsulasi selalu berakhir menjadi ViewEncapsulation.Emulated.

Saya mengonfirmasi hal ini melalui inspektur DOM karena saya tidak melihat #shadow-root di DOM. Sebaliknya, saya melihat _ngcontent-c0 yang mengonfirmasi bahwa enkapsulasi telah ditiru.


person Taranjeet Singh    schedule 18.04.2019    source sumber


Jawaban (1)


Ini tidak mungkin seperti yang Anda bayangkan, karena sudut mengkompilasi kode Anda dalam mode AOT, dan selama langkah kompilasi, browser jelas tidak dikenal.

Saya hanya bisa memikirkan satu cara untuk mencapai ini. Anda harus mengkompilasi aplikasi yang sama dua kali. Sekali untuk browser yang tidak kompatibel dengan ShadowDom, dan browser yang memungkinkan hal ini.

Kemudian di server Anda, Anda melayani apa saja yang dibutuhkan berdasarkan browser yang memintanya. Saya kira Anda juga dapat menemukan cara hacky untuk melakukannya di dalam index.html yang akan memuat perpustakaan sudut yang benar berdasarkan browser saat ini. Ini akan memerlukan beberapa skrip setelah ng build.

Anda dapat menangani enkapsulasi yang diperlukan dari dalam file lingkungan Anda, jadi jika Anda memiliki dua lingkungan berbeda untuk browser yang kompatibel dan tidak, Anda dapat menambahkan properti di dalam lingkungan Anda:

// non shadow dom compatible env
export const environment = {
  // ...
  defaultEncapsulation: ViewEncapsulation.Emulated
}


// shadow dom compatible env
export const environment = {
  // ...
  defaultEncapsulation: ViewEncapsulation.ShadowDom
}

Jika Anda memiliki dua file lingkungan untuk build produksi, Anda dapat mengedit metode bootstrapModule di dalam main.ts untuk membaca nilainya:

platformBrowserDynamic().bootstrapModule(AppModule, {
  defaultEncapsulation: environment.defaultEncapsulation
});
person Poul Kruijt    schedule 18.04.2019