我的 Angular 应用程序只是以index.html开头:
<body>
<app-root></app-root>
</body>
我希望通过在<body>
和<body class="dark-mode">
之间切换来切换,并在深色/浅色之间切换,样式如下:
body abcxyz {
color: #fff
}
body.dark-mode abcxyz {
color: #a2b3c4
}
接下来是app.component.html像往常一样带有页眉 - 主 - 页脚:
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
header.component.html有一个切换按钮:
<button (click)="onClickDarkMode()">Dark Mode</button>
我们需要一个变量和一个这样的函数才能工作,我把它们放在header.component.ts中:
isDarkMode = false;
onClickDarkMode() {
this.isDarkMode = !this.isDarkMode;
}
这个想法似乎很容易实现,但点击事件似乎在将这些行中的任何一行添加到<body>
中后一无所获:
<body [class.dark-mode]="isDarkMode">
或
<body [ngClass]="{'dark-mode': isDarkMode}">
或
<body [ngClass]="isDarkMode ? 'dark-mode' : ''">
此外,有了"暗/亮"的想法,这是通过在<body>
内切换类来实现的最佳方式吗?
你已经很接近了!我强烈建议使用服务,以便您可以在组件之间有效地共享状态。
基本上它看起来像一个服务:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ThemeService {
/**
* Variable to hold our setting.
*/
public darkMode: boolean;
/**
* Enable/disable "dark mode" by flipping the bit.
*/
public toggle(): void {
this.darkMode = !this.darkMode;
}
}
和组件:
<div class="wrapper" [class.dark-mode]="themeService.darkMode">
<div class="text">
Dark Mode Enabled? {{ themeService.darkMode ? 'YES' : 'NO' }}
</div>
<div class="button">
Parent Component
<button (click)="themeService.toggle()">Toggle!</button>
</div>
<app-child></app-child>
</div>
您将使用依赖注入来"公开"ThemeService
,如下所示:
import { Component } from '@angular/core';
import { ThemeService } from './theme.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: [ './app.component.scss' ]
})
export class AppComponent {
/**
* Inject the theme service which will be called by our button (click).
*
* @param {ThemeService} themeService instance.
*/
public constructor(public themeService: ThemeService) {
}
}
通过使用服务,您不仅可以共享状态,还可以从一个中心位置连接更多属性,如字体大小等。
我有一个简短的教程,解释了如何在项目存储库 https://github.com/mateothegreat/ng-byexamples-theme-service 的陪同下 https://matthewdavis.io/theme-service 连接东西。
希望这对您的旅程有所帮助。随时提问!
组件及其变量的作用域为 Angular。这意味着,组件中的公共变量(如isDarkMode
只有组件本身和模板知道。该变量没有全局表示形式。
虽然这有效:
<app-header>
<div [ngClass]="{'dark-mode': isDarkMode}">
</app-header>
这不会:
<body [ngClass]="{'dark-mode': isDarkMode}"></body>
您可以做的是在组件中设置body
元素的类。但请记住,您应该避免直接操作 DOM,并且您的应用程序应该与平台无关。
这就是为什么你应该使用Angular的依赖注入:
import { Component, OnInit, Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.less']
})
export class HeaderComponent implements OnInit {
darkMode: boolean = false;
constructor(
@Inject(DOCUMENT) private document: Document,
private renderer: Renderer2,
) {}
ngOnInit() {}
toggleDarkMode() {
this.darkMode = !this.darkMode;
if (this.darkMode) {
this.renderer.addClass(this.document.body, 'dark-mode');
} else {
this.renderer.removeClass(this.document.body, 'dark-mode');
}
}
}
现在只有HeaderComponent
可以更改类。您应该通过使用服务使其更加通用,以便您可以执行以下操作:
- 从应用程序中的任何位置更改模式
- 通过事件,可以在模式更改时通知其他组件