1

想象一下 Angular 组件的 my.component.scss 文件中有一个 SCSS mixin。

现在我在 Angular 应用程序的全局 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>

我的组件.ts

<pre>

 @Component({
   selector: 'my-component',
   templateUrl: './my-component.html',
   styleUrls: ['./my-component.scss']
})

</pre>

Angular 应用程序的 styles.scss。(这在 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 应该封装了“错误消息”css 类,并且它的可见性应该仅限于 my-component。在这种情况下如何保持封装工作?

PS:我只是想完成这个:https ://material.angular.io/guide/theming#theming-only-certain-components但这个问题似乎更普遍。

提前致谢。让我知道是否需要进一步澄清或代码。

4

1 回答 1

2

主题和样式封装是两个不同的东西。Angular 只会将样式代码封装在组件的样式表中;它没有封装在那里定义的任何mixin,因为必须调用mixin才能应用。你定义 mixin 的位置与应用 mixin 的位置无关——这取决于你。整个应用程序都可以访问您的错误类,因为您已在主样式表中调用(“包含”)它。

最终,您不能使用主题并将其封装,因为主题的工作方式是应用程序范围的。因此,要解决这个问题,请使用组件的选择器来限制 mixin 中类的范围:

@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 进行主题时,您不会同时导入 - 到主应用程序样式表中 - 组件的任何非主题样式。

话虽如此,您可以尝试封装您的组件主题。您需要在组件的样式表中访问全局定义的主题,并且您可能还必须将角度材料主题实用程序导入到组件样式表中。我不确定这是否可行,而且我认为如果您对很多组件执行此操作,它可能会在您的应用程序中添加大量样式重复。

于 2018-06-08T19:38:13.693 回答