想象一下,在Angular组件的my.component.scss文件中有一个SCSS mixin .
现在我在Angular app的全局style.scss中导入该文件,因为我想将一些数据传递给mixin .
例如: my-component.scss.
<pre>
@mixin my-component-theming($theme) {
// Extract whichever individual palettes you need from the theme.
$warn-palette: map-get($theme, warn);
$warn: mat-color($primary-palette);
.error-message {
color: $warn !important;
}
}
</pre>
my-component.ts
<pre>
@Component({
selector: 'my-component',
templateUrl: './my-component.html',
styleUrls: ['./my-component.scss']
})
</pre>
Angular application's styles.scss. (This gets imported in Angular.json)
<pre>
@import '~@angular/material/theming';
@import 'my-component.scss';
// just imagine that $app-theme is already defined here.
// Not including unnecessary code to keep example simple.
@include my-component-theming($app-theme)
</pre>
它按预期编译和应用程序工作,但我的“错误消息”css类可以通过整个应用程序访问 .
Angular should have encapsulated "error-message" css class and it's visibility should be limited to my-component only. How can I keep the encapsulation working in this case?
PS: 我只是想完成这个:https://material.angular.io/guide/theming#theming-only-certain-components但这个问题似乎更为普遍 .
提前致谢 . 如果需要进一步澄清或代码,请与我们联系 .
1 回答
主题和风格封装是两回事 . Angular只会将样式代码封装在组件的样式表中;它不会封装那里定义的任何mixins,因为必须调用mixins才能应用 . 你定义mixin的地方与mixin的应用位置无关 - 这取决于你 . 您的错误类可以被整个应用程序访问,因为您已在主样式表中调用('included')它 .
最终你不能使用主题并将其封装,因为主题的工作方式是应用程序范围 . 因此,要解决这个问题,请使用组件的选择器来限制mixin中类的范围:
这仍然定义了样式应用程序范围,但它只会影响您的组件 .
此外,您不应在组件样式表中包含组件主题mixin . 它们应该在他们自己的主题文件中,这样当你导入mixin用于主题时,你也不会导入 - 进入你的主应用程序样式表 - 组件的任何非主题样式 .
话虽这么说,你可以尝试封装你的组件主题 . 您需要在组件中访问全局定义的主题's style sheet, and you might also have to import the angular material theming utilities into your component style sheet as well. I'我不确定这是否有效,我认为如果您为很多组件执行此操作,它可能会在您的应用中添加大量样式重复 .