【问题标题】:Angular2: Custom material theme in each lazy loaded submoduleAngular2:每个延迟加载的子模块中的自定义材质主题
【发布时间】:2019-07-05 12:05:11
【问题描述】:

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

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

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

一些 Material 组件应用自定义主题(按钮),而一些(mat-form-field)只采用 style.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 将应用于 home-app.component.html 中使用的一些材质组件,而某些材质组件将使用 home-app.component.scss 中指定的导入主题em>

【问题讨论】:

  • 在根组件级别注意到方括号中的共享 css 或 scss。 stackoverflow.com/questions/35702164/…
  • 还有 angular.io 中的共享 ngmodules angular.io/guide/sharing-ngmodules 它可能是一个很好的资源。
  • 我注意到的一件事是当我添加另一个模块时,其中没有任何内容,我的子模块使用对话框和一些按钮在厌倦了许多其他事情后开始神奇地工作。奇怪的是,其他一些物质对象工作得很好,但按钮却不行。就像与子模块共享 app.module 资源有些不一致。
  • 这里的问题是,将自定义主题应用于 Angular Material 需要不限定样式。意味着主题样式应该是全球性的。您可以在某些根选择器的范围内定义一些主题,例如 #id2

标签: angular angular-material2


【解决方案1】:

我想我理解你的问题,这里有一个适合你的解决方案:)

因此,当您使用带有 opt in 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 类中来应用主题。例如,在根 .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 类的容器中并获得所需的结果(每个延迟加载的模块都有不同的主题)。请记住,我们只是在需要自定义主题的地方导入 import '~@angular/material/theming';`。

这是一个活生生的例子:CodeSandbox

【讨论】:

  • 注意:'~@angular/material/theming' 的第一次导入中缺少'@';从导入'~@angular/material/theming'; --> @import '~@angular/material/theming';
【解决方案2】:

尝试添加ng generate module Shared,它将在AppModule 旁边的根目录下创建SharedModule,其中没有任何内容。出于某种原因,当它重新编译时,它可能会神奇地将您的一些子模块重新连接到像 Angular Material Themes 这样的主题。不知道引擎盖下发生了什么。

【讨论】:

    【解决方案3】:

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

    @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
    })
    

    【讨论】:

      猜你喜欢
      • 2023-04-11
      • 2017-08-21
      • 2017-02-22
      • 2017-07-12
      • 2017-09-03
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 2018-05-22
      相关资源
      最近更新 更多