Angular2:每个延迟加载子模块中的自定义材质主题

时间:2019-02-11 22:15:36

标签: angular angular-material2

在Angular 7应用的单独子模块中加载自定义Angular Material 2主题的问题

我有角度包装器模块(应用程序模块)和许多独立的延迟加载子模块。每个子模块的行为就像一个完全独立的应用程序,并且需要自己的棱角材质主题。

我已经为每个子模块创建了自定义主题,并尝试使用相对路径在每个组件的 .scss 文件中引用该自定义主题。

某些Material组件应用自定义主题(按钮),而某些(mat-form-field)仅采用styles.scss中指定的主题。

我可以避免这种情况的一种方法是将每个自定义主题包含在angular.json的“样式”数组中,但恐怕这样做会导致每个独立的子模块(应用程序)必须加载每个主题”编译的.css文件,将产生开销。

此解决方案或任何更好的解决方案是否存在已知问题?

home-app.component.scss

@import './theme.scss';

VS。

angular.json

...
"styles": [
    "src/styles.scss",
    "src/app/orgs/home/theme.scss" // <-- FIXED BY ADDING THIS
],
...

预期: home-app.component.scss 中声明的主题将被加载并应用于home-app.component.html

中使用的每个材料组件。

实际: 如果我不将“ src / app / orgs / home / theme.scss” 添加到 angular.json ,则以 styles.scss < / em>将应用于 home-app.component.html 中使用的某些材质组件,而某些材质组件将使用 home-app.component.scss 中指定的导入主题em>

3 个答案:

答案 0 :(得分:2)

您是否尝试将其直接添加到组件的样式数组中?

@Component({
  selector: 'app-home',
  template: 'your-template.html',
  styles: ['your-style.scss', 'your-theme.scss']
})

您可以做的另一件事是将ShadowDom用作ViewEncapsulation:

@Component({
  selector: 'app-home',
  template: 'your-template.html',
  styles: ['your-style.scss', 'your-theme.scss'],
  encapsulation: ViewEncapsulation.ShadowDom
})

答案 1 :(得分:1)

我认为我了解您的问题,这是为您提供的解决方案:)

因此,当您使用cli在material-theming中使用cli创建一个新的ng-project时,您将获得如下所示的初始主题配置(或者您可以在Material Guides中找到该配置)

import '~@angular/material/theming';
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$candy-app-primary: mat-palette($mat-indigo);
$candy-app-accent:  mat-palette($mat-pink, A200, A100, A400);

// The warn palette is optional (defaults to red).
$candy-app-warn:    mat-palette($mat-red);

// Create the theme object (a Sass map containing all of the palettes).
$candy-app-theme: mat-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn);

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($candy-app-theme);

其中最重要的部分是要记住,您必须在应用程序中仅包含一次mat-core()(为了拥有单个材料样式的css文件)。

此后,您可以通过在应用程序中的任意位置添加import '~@angular/material/theming';来创建自定义主题,并将主题包装在css calss中来应用主题。例如,在根.scss文件中一次包含mat-core之后,在延迟加载的模块中,您可以执行以下操作:

@import "~@angular/material/theming";

.theme1 {
  $theme-primary: mat-palette($mat-red);
  $theme-accent: mat-palette($mat-lime, A200, A100, A400);

  // The warn palette is optional (defaults to red).
  $theme-warn: mat-palette($mat-red);

  // Create the theme object (a Sass map containing all of the palettes).
  $theme-theme: mat-light-theme($theme-primary, $theme-accent, $theme-warn);

  // Include theme styles for core and each component used in your app.
  // Alternatively, you can import and @include the theme mixins for each component
  // that you are using.
  @include angular-material-theme($theme-theme);
}
<div class="theme1">
  <mat-toolbar color="accent">
    <button color='primary' mat-button routerLink="/1">Go to 1</button>
    <button color='primary' mat-button routerLink="/2">Go to 2</button>
  </mat-toolbar>
</div>

当然,除了两个按钮,您还可以将路由器出口放在类theme1的容器内,并获得所需的结果(每个懒加载模块的主题不同)。请记住,我们只是在需要自定义主题的地方导入导入'〜@ angular / material / theming';`。

这是一个实时示例:CodeSandbox

答案 2 :(得分:0)

尝试仅添加ng generate module Shared,它将在AppModule旁边的根目录中创建SharedModule,其中没有任何内容。由于某种原因,它可能会重新神奇地将您的某些子模块重新连接到诸如Angular Material Themes之类的主题。不知道到底发生了什么。