首页 > 解决方案 > 嵌套 Angular Material 自定义组件主题

问题描述

我创建了两个自定义 Angular Material 主题(蓝色、红色)。

根据“Theming your components”材料文档,我有一个IconComponent(选择器:)我想使用主题进行设计。my-app-icon

现在,在我的 中styles.scss,我有:

@mixin icon-theme($theme) {
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);

  my-app-icon {
    background-color: mat-color($primary);
    color: mat-color($accent, A400);
  }
}

.blue-theme {
   @include angular-material-theme($blue-theme);
   @include icon-theme($blue-theme);
}

.red-theme {
   @include angular-material-theme($red-theme);
   @include icon-theme($red-theme);
}

它运作良好,但如果我想嵌套我的主题,例如:

<div class="blue-theme">
  <my-app-icon></my-app-icon>
  <div class="red-theme">
    <my-app-icon></my-app-icon>
  </div>
</div>

只有第一个主题声明blue-theme此处)有效(对于两个图标)。这是有道理的,因为我的 mixin 暗示了my-app-icon {}.

如何获得预期的行为(第一个图标蓝色,第二个红色)?

标签: angularsassangular-material

解决方案


在应用程序中同时使用多个主题需要一种不同于全局实现可切换主题的方法,这是您已经实现的。

您需要在组件中实现“主题”或颜色功能 - 就像 Angular Material 通过CanColor基类在某些组件上为“颜色”选项(主要、重音、警告)所做的那样。

简而言之,您的组件有一些机制来指定其主题,并且您在组件内实现样式。

这可以像一个类一样简单:

用法:

<my-app-icon class="red-theme"></my-app-icon>

SCSS:

:host(.red-theme) {
  @include icon-theme($red-theme); 
}
:host(.blue-theme) {
  @include icon-theme($blue-theme); 
}

或者它可能更复杂,例如Input主题属性:

用法:

<my-app-icon theme="red"></my-app-icon>

TS:

@Input() theme: string = 'red'; // defaults to red
@HostBinding('class.red-theme') get isRedTheme() { return this.theme === 'red'; };
@HostBinding('class.blue-theme') get isBlueTheme() { return this.theme === 'blue'; };

与上述相同的 SCSS 将适用于此。

您可以选择仅对组件的必要部分进行样式设置:

图标组件模板:

<mat-icon [ngClass]="{'blue-theme': theme === 'blue', 'red-theme': theme !== 'blue'}">{{iconName}}</mat-icon>

SCSS:

:host {
  mat-icon
    &.red-theme {
      color: red;
    }
    &.blue-theme {
      color: blue;
    }
  }
}

但这可能通过主题混合更棘手。

看看CanColor课程的想法:

https://github.com/angular/components/blob/8.1.x/src/material/core/common-behaviors/color.ts


推荐阅读