通过标题组件中的按钮切换类,该按钮通过 Angular 6+ 影响主应用程序组件



我的 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可以更改类。您应该通过使用服务使其更加通用,以便您可以执行以下操作:

  • 从应用程序中的任何位置更改模式
  • 通过事件,可以在模式更改时通知其他组件

最新更新