我有一个使用Material 2的Angular 4应用程序(当前版本,2.0.0-beta.11)。
我跟随documentation主题并创建了两个主题,一个轻主题和一个黑暗主题。由于我没有使用md-sidenav组件,因此我将mat-app-background
类放在body元素上,该元素应用当前主题的背景颜色(浅色主题为浅灰色,深灰色)一个黑暗的主题。)
问题在于,当切换我的主题切换器时(一个添加或删除类的简单按钮,没有什么花哨的,like this answer),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);
}
单击按钮时,它成功切换主题:应用类,按钮将颜色从浅色主色原色更改为暗色主色原色。但背景颜色仍然是浅色主题的背景色。
默认背景颜色&#34;坚持&#34;并且不受主题开关的影响。我缺少什么?有没有办法让背景颜色自动更新,而无需使用mixin / manual重新定义?
(注意:干净的角度cli项目,使用直接从角度材料文档中粘贴的主题副本.Angular 4.4.4,material 2.0.0-beta.11。)
答案 0 :(得分:7)
我在角度材料2 github项目的封闭问题中找到了答案indirectly acknowledged,因此我将在下面概述正在发生的事情以及我如何应用变通方法来处理这个“功能”。
也就是说,如果您将整个应用程序嵌套在md-sidenav
(或mad-sidenav
)组件中,那么您就可以了,因为它是一个Material组件。但是如果您没有使用它,而是按照文档中的说明选择应用mat-app-background
的路线,那么只会获得初始应用主题的样式。
为了使这适用于非材质组件元素(例如常规html元素),您需要应用scss mixin才能应用这些样式。此外,您需要手动设置所有非材质成分元素的样式。
首先,我更新了我的theme.scss,以包含一个定位main
元素的mixin。正如在我的初始帖子中,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
}
}
这里我手动将主题的背景颜色和前景色分别作为主要元素的背景和字体颜色应用。重要的是要注意我已将主要元素的一般样式调整为浏览器窗口的完整高度。
要应用此功能,我{sa}文件中主题类定义中的@include
。重要的是,我还必须将我的默认主题分配给自己的类;否则默认值将始终触发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覆盖,以便应用于drop等元素下降和日期选择器。 (令人讨厌,但在测试版的这一点上你必须手动完成。)
为了支持两个不同的主题类,我简单地调整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
项目合并到角度材质项目时,cdk
被删除。对于较新的项目,您需要直接操纵DOMTokenList,例如{{1} }}。)
应用所有这些更改后,现在可以在浅色和深色主题之间切换。
将应用程序嵌套在sidenav中可能更容易,只是不使用sidenav部分。
答案 1 :(得分:0)
这次聚会很晚了,但是如果您的 Angular 应用程序没有嵌套在父 Material 组件中,它将不会采用您设置的主题属性。正如@RoddyoftheFrozenPass 所提到的,这可以通过将您的应用程序封装在一个像 side-nav
这样的材料组件中来解决,但是将 mat-app-background
类添加到 {{1} 中的 body
元素更容易}}。