【发布时间】:2021-04-26 15:16:58
【问题描述】:
场景
我们遵循此tutorial 为我们的用户提供深色和浅色主题。
问题
浏览器加载预期的 css 文件(深色或浅色)。然而,这些样式并没有应用于我们的组件。
这发生在<head></head>:
<link rel="stylesheet" type="text/css" href="theme-dark.css">
或
<link rel="stylesheet" type="text/css" href="theme-light.css">
如您所见,浏览器正确切换了两个主题。
代码 angular.json
"styles": [
"projects/menu/src/styles.scss",
{
"input": "projects/menu/src/theming/theme-dark.scss",
"bundleName": "theme-dark",
"inject": false
},
{
"input": "projects/menu/src/theming/theme-light.scss",
"bundleName": "theme-light",
"inject": false
}
],
theme-service.ts
private _mainTheme$: BehaviorSubject<string> = new BehaviorSubject(
'theme-light'
);
private _darkMode$: BehaviorSubject<boolean> = new BehaviorSubject(false);
darkMode$: Observable<boolean> = this._darkMode$.asObservable();
private _renderer: Renderer2;
private head: HTMLElement;
private themeLinks: HTMLElement[] = [];
theme$: Observable<[string, boolean]>;
constructor(
rendererFactory: RendererFactory2,
@Inject(DOCUMENT) document: Document
) {
this.head = document.head;
this._renderer = rendererFactory.createRenderer(null, null);
this.theme$ = combineLatest([this._mainTheme$, this._darkMode$]);
this.theme$.subscribe(async ([mainTheme, darkMode]) => {
const cssExt = '.css';
const cssFilename = darkMode
? 'theme-dark' + cssExt
: mainTheme + cssExt;
await this.loadCss(cssFilename);
if (this.themeLinks.length == 2)
this._renderer.removeChild(this.head, this.themeLinks.shift());
});
}
setMainTheme(name: string) {
this._mainTheme$.next(name);
}
setDarkMode(value: boolean) {
this._darkMode$.next(value);
}
private async loadCss(filename: string) {
return new Promise((resolve) => {
const linkEl: HTMLElement = this._renderer.createElement('link');
this._renderer.setAttribute(linkEl, 'rel', 'stylesheet');
this._renderer.setAttribute(linkEl, 'type', 'text/css');
this._renderer.setAttribute(linkEl, 'href', filename);
this._renderer.setProperty(linkEl, 'onload', resolve);
this._renderer.appendChild(this.head, linkEl);
this.themeLinks = [...this.themeLinks, linkEl];
});
}
theme-base.scss
@import '~@angular/material/theming';
@include mat-core();
@mixin theming($theme) {
@include angular-material-theme($theme);
}
theme-dark.scss
@import '~@angular/material/theming';
@import './theme-base';
@include mat-core();
// color palette definitions
$primary: mat-palette($dark-md-mcgpaletteblack);
$accent: mat-palette($md-mcgpalettewhite);
$warn: mat-palette($dark-md-mcgpalettered);
$background:mat-palette($dark-md-mcgpalettebackground);
$confirm: mat-palette($dark-md-mcgpaletteorange);
$theme-dark: mat-dark-theme((color: (primary: $primary,
accent: $accent,
warn: $warn,
background: $background,
confirm: $confirm)));
theme-dark.scss - 看起来一样
在style.scss 中我们导入了两个主题:
styles.scss
@import 'projects/menu/src/theming/theme-dark.scss';
@import 'projects/menu/src/theming/theme-light.scss';
.theme-dark {
@include angular-material-theme($theme-dark)
}
.theme-light {
@include angular-material-theme($theme-light)
}
然后我们使用这些变量:
styles.scss
body {
background: mat-color($background, default);
}
h1 {
color: mat-color($accent, default);
}
但目前我们也将它们导入到我们的组件中。我认为这是一回事,那是错误的。
对话框如下所示:
@import 'projects/menu/src/theming/theme-dark.scss';
@import 'projects/menu/src/theming/theme-light.scss';
.theme-dark {
@include angular-material-theme($theme-dark)
}
.theme-light{
@include angular-material-theme($theme-light)
}
.mat-button {
color: mat-color($accent, default);
background-color: mat-color($confirm, default);
}
我尝试了什么:
- 删除每个样式表中两个主题的导入。颜色仍然受
style.scss中主题导入顺序的影响。最后使用深色主题 -> 将使用深色主题,反之亦然。 - 对主题使用与教程中相同的变量。但后来我们不得不改变所有的
background-color: mat-color($confirm, default); - 等等。花了很多时间...
我们无法弄清楚如何将缺少的部分组合在一起。我们需要使用mixins吗?还是我们缺少在根组件上设置 dark-theme 类?
非常感谢您。
【问题讨论】:
标签: css angular sass angular-material themes