PrimeNG 元素没有作用域,不能使用默认的 Angular 2 ViewEncapsulation (Emulated) 设置样式
Posted
技术标签:
【中文标题】PrimeNG 元素没有作用域,不能使用默认的 Angular 2 ViewEncapsulation (Emulated) 设置样式【英文标题】:PrimeNG Element not scoped, can't be styled with default Angular 2 ViewEncapsulation (Emulated) 【发布时间】:2016-11-30 16:03:32 【问题描述】:在声明我的 Angular 2 组件以利用 View Encapsulation 时,我尝试使用 styleUrls
属性,但在 Angular 完成初始化后将元素插入 DOM 时似乎存在问题。
我的情况是 PrimeNG paginator,我目前无法设置它的样式,因为它没有被 Angular 应用范围。
见下文<p-datatable>
元素有一个范围(它存在于原始标记中)但<p-paginator>
没有(事后添加到DOM)。
因此,Angular 插入HEAD
的样式与我的元素不匹配:
<style>
p-datatable[_ngcontent-xnm-4] p-paginator[_ngcontent-xnm-4]:not(:first-child)
display: none;
</style>
这是 Angular 2 中视图封装的限制,还是有办法让它按需“重新调整”DOM 的范围?
编辑错字并澄清标题
【问题讨论】:
我面对的是the same issue with ng-bootstrap,Angular UI 团队提出了相同的解决方案,使用:host \deep\
。所以我猜 Angular 没有提供动态添加元素范围的方法。
【参考方案1】:
正如您所注意到的,这是因为 Shadow DOM 及其提供的样式范围。您的模板仅包含正确获得作用域的p-datatable
,但它在事后添加的子元素没有作用域。为了应用您的自定义样式,您可以选择两种方法。
解决方案 1 - 特殊选择器(推荐)
我个人推荐这样做,因为您仍然可以维护视图封装(Shadow DOM)。我们仍然可以通过使用:host
和/deep/
selectors 来定位使用PrimeNG 的组件级模板
:host /deep/ .ui-paginator-bottom
display: none;
这样做是强制一个样式通过子组件树进入所有子组件视图,因此即使 p-datatable
是您组件自己的模板中存在的唯一标签,该样式仍将被应用,因为它是DOM 中组件的子组件。
解决方案 2 - 禁用视图封装
在组件级别,您可以通过将其设置为 ViewEncapsulation.None 来禁用 View Encapsulation
...
import ..., ViewEncapsulation from '@angular/core';
@Component
...
encapsulation: ViewEncapsulation.None,
【讨论】:
如果我能投票 10 次就好了。这个答案是完美的,我在他们的文档或论坛中的任何地方都找不到这个信息。谢谢! 我 100% 同意 reflog。在过去的 3 个小时里一直在寻找这个解决方案。谢谢! 很好的答案!这对我有很大帮助! 哇,我真的从来没有见过 ":host" 或 "/deep" 深度选择器......从来没有。 仅供将来参考:注意encapsulation: ViewEncapsulation.None
意味着@import
的任何作用域也被忽略。所以,即使在.non-existing @import '../../node_modules/bootstrap/scss/bootstrap';
中使用一些.non-existing
也没有效果;导入的 CSS 仅适用于整个页面。 (同样,一些.existing @import '...';
可能看起来有效,但实际上也忽略了.existing
。)换句话说,当使用Angular CLI 6 时,可能只是将样式添加到angular.json
。以上是关于PrimeNG 元素没有作用域,不能使用默认的 Angular 2 ViewEncapsulation (Emulated) 设置样式的主要内容,如果未能解决你的问题,请参考以下文章