#angular #web-component
#angular #веб-компонент
Вопрос:
Я пытаюсь инициализировать компонент с теневым DOM или без него на основе браузера (поскольку IE не поддерживает теневой DOM).
Я проверяю, является ли это IE11, и устанавливаю значение инкапсуляции Emulated
для IE и ShadowDom
для других браузеров.
const agent = window.navigator.userAgent;
const isIe11 = agent.indexOf('MSIE') === -1 amp;amp; agent.indexOf('Trident') > 0;
@Component({
selector: 'my-web-component',
templateUrl: '...html',
styleUrls: ['...scss'],
encapsulation: isIe11 ? ViewEncapsulation.Emulated : ViewEncapsulation.ShadowDom
})
export class NavbarComponent implements OnInit { ... }
Значение isIe11
является правильным в соответствии с возвращаемым значением проверки браузера, но инкапсуляция всегда заканчивается ViewEncapsulation.Emulated
.
Я подтвердил это через инспектор DOM, потому что я не вижу #shadow-root
в DOM. Вместо этого я вижу _ngcontent-c0
, что подтверждает, что инкапсуляция эмулируется.
Ответ №1:
Это невозможно в том виде, в каком вы себе это представляете, потому что angular компилирует ваш код в режиме AOT, и на этапе компиляции браузер, очевидно, неизвестен.
Я могу придумать только один способ добиться этого. Вам нужно скомпилировать одно и то же приложение дважды. Один раз для ShadowDom
несовместимого браузера, и тот, в котором это возможно.
Затем на вашем сервере вы обслуживаете то, что необходимо, на основе запроса браузера. Я полагаю, вы также можете найти хакерский способ сделать это внутри index.html
, который загрузит правильные библиотеки angular на основе текущего браузера. Для этого потребуется некоторый ng build
сценарий after.
Однако необходимую инкапсуляцию можно выполнить из файла среды, поэтому, если у вас две разные среды для совместимых и несовместимых браузеров, вы можете добавить свойство внутри своей среды:
// non shadow dom compatible env
export const environment = {
// ...
defaultEncapsulation: ViewEncapsulation.Emulated
}
// shadow dom compatible env
export const environment = {
// ...
defaultEncapsulation: ViewEncapsulation.ShadowDom
}
Если у вас есть эти два файла среды для ваших производственных сборок, вы можете отредактировать bootstrapModule
метод внутри вашего main.ts
, чтобы прочитать значение:
platformBrowserDynamic().bootstrapModule(AppModule, {
defaultEncapsulation: environment.defaultEncapsulation
});