angular - 如何为 Web 组件动态设置 ViewEncapsulation?
问题描述
我正在尝试基于浏览器初始化带有或不带有 Shadow DOM 的组件(因为 IE 不支持 Shadow DOM)。
我检查它是否是 IE11 并将封装设置Emulated
为 IE 和ShadowDom
其他浏览器。
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 { ... }
根据浏览器检查的返回值,的值isIe11
是正确的,但封装总是以ViewEncapsulation.Emulated
.
我通过 DOM 检查器确认了这一点,因为我#shadow-root
在 DOM 中看不到。相反,我看到_ngcontent-c0
哪个确认封装是模拟的。
解决方案
这在您的设想中是不可能的,因为 Angular 在 AOT 模式下编译您的代码,并且在编译步骤期间浏览器显然是未知的。
我只能想到一种方法来实现这一点。您必须编译相同的应用程序两次。一次用于不ShadowDom
兼容的浏览器,而在其中一种是可能的。
然后在您的服务器上,根据请求的浏览器提供所需的服务。我想您还可以在index.html
其中找到一种 hacky 方法来执行此操作,该方法将根据当前浏览器加载正确的角度库。这将需要一些ng build
脚本后。
不过,您可以在环境文件中处理所需的封装,因此如果您有两个不同的环境用于兼容和不兼容的浏览器,您可以在环境中添加一个属性:
// 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
});
推荐阅读
- ajax - 使用数据表时如何解决jQuery ajax中的以下错误
- javascript - 如何以编程方式修复已经发生的 webGL 上下文丢失(chrome 中的悲伤微笑)?
- openssl - openssl 解密问题因 EVP_DecryptFinal_ex 失败:解密错误
- mysql - EF Core (usdig Raw Sql) 中的 System.InvalidCastException 错误,当查询不返回行时(但在查询返回行时工作)
- mongodb - Mongo DB是否将所有内容写入oplog
- typescript - Eslint 标记为未定义的类成员,充当默认参数值
- swift - Alamofire:错误域=NSURLErrorDomain 代码=-1004“无法连接到服务器。” 在同一应用会话中尝试从 https 切换到 http
- java - 我想使用 Glen K. Peterson 的 Pdf Layout Manager 构建一个 PDF 文档,但我坚持构建一个表格
- inno-setup - 在 Inno Setup 中使用 3rd 方 API 的代理和虚拟机过滤器
- html - 如何缩小引导程序中jumbotron和about部分之间的差距