Angular component's style view encapsulation does not work when component scss file is imported to styles scss file
想象一下,Angular组件的my.component.scss文件中有一个SCSS mixin。
现在,我要在Angular应用程序的global.scss中导入该文件,因为我想将一些数据传递给该mixin。
例如:
my-component.scss。
1 2 3 4 5 6 7 8 9 10 11 | [cc] @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; } } |
code> pre>
我的component.ts
1 2 3 4 5 6 7 | [cc] @Component({ selector: 'my-component', templateUrl: './my-component.html', styleUrls: ['./my-component.scss'] }) |
code> pre>
Angular应用程序的styles.scss。 (这将导入Angular.json)
1 2 3 4 5 6 7 8 | [cc] @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) |
code> pre>
它确实可以按预期进行编译和应用程序工作,但是整个应用程序都可以访问我的"错误消息" css类。
Angular应该已经封装了"错误消息" css类,并且它的可见性应该仅限于my-component。在这种情况下,如何保持封装正常工作?
PS:我只是想做到这一点:https://material.angular.io/guide/theming#theming-only-certain-components,但是这个问题似乎更笼统。
提前致谢。让我知道是否需要进一步说明或代码。
主题和样式封装是两件事。 Angular只会将样式代码封装在组件的样式表中;它没有封装在那里定义的任何混合包,因为必须调用混合包才能应用。定义混合的位置与应用混合的位置无关-这取决于您。您可以在整个应用程序中访问您的错误类,因为您已在主样式表中对其进行了调用("包含")。
最终,您不能使用主题并将其封装,因为主题的工作方式是整个应用程序范围。因此,为了解决这个问题,请使用组件的选择器来限制mixin中类的范围:
1 2 3 4 5 6 7 8 9 10 | @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); my-component.error-message { color: $warn !important; } } |
这仍然在整个应用程序中定义了样式,但是只会影响您的组件。
此外,您不应在组件样式表中包括组件主题混合。它们应位于自己的主题文件中,以便在导入用于主题的mixin时,也不会将组件的任何非主题样式都导入到主应用程序样式表中。
话虽如此,您可以尝试封装组件主题。您可能需要访问组件样式表中的全局定义主题,并且可能还必须将角度材质主题实用程序导入到组件样式表中。我不确定这是否行得通,并且如果您对许多组件执行此操作,则可能会在您的应用程序中添加很多样式重复。