我使用材料2(当前版本,2.0.0-beta.11)。
我遵循了主题的文档,并创建了两个主题,一个灯主题和一个黑暗主题。由于我不使用MD-Sidenav组件,因此我将mat-app-background
类放在身体元素上,该类别应用了当前主题的背景颜色(浅灰色用于轻型主题,以及深灰色的深灰色主题。)p>问题是,当我的主题切换器被切换时(一个添加或删除类的简单按钮,没有幻想,像这样的答案)时,mat-app-background
中的背景颜色未更新。
我无法创建成功使用自定义主题的Plunker,但这是基本要素:
index.html
<body class="mat-app-background">
<app-root></app-root>
</body>
app.component.html
<main [class.dark-theme]="isDarkTheme">
<button md-raised-button color="primary" (click)="toggleTheme()">Toggle</button>
<!-- other content -->
</main>
app.component.ts
isDarkTheme: boolean = false;
toggleTheme() { this.isDarkTheme = !this.isDarkTheme; }
theme.scss
@import '~@angular/material/theming';
@include mat-core();
// light (default) theme
$lt-primary: mat-palette($mat-indigo);
$lt-accent: mat-palette($mat-pink, A200, A100, A400);
$lt-theme: mat-light-theme($lt-primary, $lt-accent);
@include angular-material-theme($lt-theme);
// alternate dark theme
$dark-primary: mat-palette($mat-blue-grey);
$dark-accent: mat-palette($mat-amber, A200, A100, A400);
$dark-warn: mat-palette($mat-deep-orange);
$dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
.dark-theme {
@include angular-material-theme($dark-theme);
}
当我单击按钮时,它成功切换了主题:应用类,按钮从光主题主颜色变为深色主题主颜色。但是背景颜色仍然是光主题的背景颜色。
默认背景颜色" sticks",不受主题开关的影响。我缺少什么?有没有办法使背景颜色为自动更新而没有Mixin/Manual Redefinition?
(注意:清洁角CLI项目,使用直接从角材料文档粘贴的主题复制。Angular 4.4.4,材料2.0.0-Beta.11。)
我发现答案在Angular Material 2 GitHub项目上的封闭问题中间接确认,因此我将在下面概述正在发生的事情以及如何应用解决方案来处理此功能"。"
角材料2主题仅适用于材料组件。
也就是说,如果您将整个应用程序嵌套在md-sidenav
(或mad-sidenav
)组件中,则您可以很好,因为那是材料组件。但是,如果您不使用它,而是按照文档中指示的应用mat-app-background
的途径,您只能获得初始应用的主题样式。
为了使此功能用于非物质组件元素(例如常规HTML元素),您需要应用SCSS Mixin以应用这些样式。此外,您需要手动的非物质组件元素的所有样式。
开始,我更新了主题。Scss以包括针对main
元素的混合蛋白。与我的初始帖子一样, main
包装了整个app.component,是我应用深色主题类的类。
@mixin html-theme($theme) {
& {
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);
background-color: mat-color($background, background);
color: mat-color($foreground, text);
// other html element styling here
}
}
在这里,我将主题的背景颜色和前景颜色分别应用于主元素上。重要的是要注意,我已经将主要元素的一般样式调整为浏览器窗口的整个高度。
要应用此信息,i @include
在SASS文件中主题类定义中的Mixin。重要的是,我还必须将我的默认主题分配给自己的班级。否则,默认值将始终触发混音并用默认的主题覆盖活动主题的样式。
// light (default) theme
.light-theme {
$lt-primary: mat-palette($mat-indigo);
$lt-accent: mat-palette($mat-pink, A200, A100, A400);
$lt-theme: mat-light-theme($lt-primary, $lt-accent);
@include angular-material-theme($lt-theme);
@at-root main.light-theme {
@include html-theme($lt-theme);
}
}
// alternate dark theme
.dark-theme {
$dark-primary: mat-palette($mat-blue-grey);
$dark-accent: mat-palette($mat-amber, A200, A100, A400);
$dark-warn: mat-palette($mat-deep-orange);
$dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn);
@include angular-material-theme($dark-theme);
@at-root main.dark-theme {
@include html-theme($dark-theme);
}
}
我使用SASS @at-root
指令仅重新定位main
元素的原因是因为主题类还需要应用于CDK覆盖层,以便将其应用于诸如下拉菜单和日期选择器之类的元素。(令人讨厌,但是在Beta的这一点上,您必须手动进行。)
为了支持两个不同的主题类,我对app.component.html进行了调整,以在'light-theme'和'dark-theme之间切换:
<main [class.dark-theme]="isDarkTheme" [class.light-theme]="!isDarkTheme">
,如前所述,我们还需要重新主导CDK覆盖层,因此我更新到app.component.ts文件以将适当的主题类添加到其中:
isDarkTheme = false;
constructor(private overlayContainer: OverlayContainer) {
this.setOverlayClass();
}
toggleTheme() {
this.isDarkTheme = !this.isDarkTheme;
this.setOverlayClass();
}
private setOverlayClass() {
this.overlayContainer.themeClass = (this.isDarkTheme ? 'dark-theme' : 'light-theme');
}
(注意,将theme-class
合并到Angular材料项目中时删除了CC_11。对于较新的项目,您需要直接操纵Domtokenlist,例如overlayContainer.getContainerElement().classList.toggle('light-theme')
。)
随着所有这些更改的应用,在光和黑暗主题之间切换。
将您的应用程序嵌套在侧列中并且不使用Sidenav部分可能会更容易。
这方很晚,但是如果您的Angular应用不在父材材料组件中嵌套,则不会占用您设置的主题属性。正如@roddyofthefrozenpass提到的那样,可以通过将您的应用程序封装在side-nav
等材料组件中来解决,但是只需将mat-app-background
类添加到index.html
中的body
元素。
https://material.angular.io/guide/theming