【问题标题】:How to toggle dark theme in Angular when I click on the switch?单击开关时如何在 Angular 中切换深色主题?
【发布时间】:2020-05-30 20:56:35
【问题描述】:

我正在使用 Angular,我正在尝试在浅色和深色主题之间切换。切换开关在我的标题组件中。请看下文

而我的header组件是app组件中的子组件。另见下文

// app.component.html    

    <app-header (mode)="receiveMode($event)"></app-header>

     <router-outlet></router-outlet>

因此,我在我的头组件 TS 文件中设置了切换主题的布尔值

// header.component.ts

import { Component, OnInit , Output, EventEmitter} from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  @Output() mode = new EventEmitter<boolean>();

  setDark = false;

  constructor() { }

  ngOnInit(): void {

  }

  onChangeToggle() {
    this.setDark = !this.setDark;
    this.mode.emit(this.setDark);
    console.log(this.setDark);
  }

}

然后,我使用 Output 装饰器将该值传递给父组件,并在 app.component.ts 文件中接收它,以便所有其他组件也可以拥有主题(不仅仅是 HomeComponent)。

// app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  setMode = false;

  receiveMode($event) {
    this.setMode = $event;
    console.log("MODEEEE", this.setMode);
  }


  title = 'about-me';
}

然后我从 app.component.html 文件中的 app-header 接收布尔值

// app.component.html

    <app-header (mode)="receiveMode($event)"></app-header>

    <router-outlet></router-outlet>

我在styles.css 中将darkTheme 类添加到我的全局样式表中

.darkTheme {
    background-color: black;
}

我想知道如何使用 ngClass 或 ngStyle 根据布尔值有条件地设置它。

【问题讨论】:

  • 只需将darkTheme 类添加到您覆盖的文档正文中,位于styles.css 中

标签: javascript html css angular class


【解决方案1】:

这是一种方法:

<div [ngClass]="{
  darkTheme: setMode
}">
</div>

您还可以在同一个 ngClass 中添加其他类和条件。

另一个:

<div [class.darkTheme]="setMode"></div>

编辑:正如我在评论中提到的,我更喜欢这种方法:

<link rel="stylesheet" href="/theme/css/dark-theme.min.css" *ngIf="setMode">

【讨论】:

  • 嗨,我试过了,但我的组件无权访问应用程序组件中的 setMode。由于没有父子关系,因此也无法通过 Input() 或 Output() 传递。无论如何感谢您的回复!
  • @kennyman335 我只回答“我想知道如何使用 ngClass 或 ngStyle 根据布尔值有条件地设置它”,这是您帖子中唯一的问题(可以考虑)。此外,如果您使用的是主题,那么任何子组件都应该忽略主题更改。您最好导入一个以 html 元素为目标的 dark-theme.css 并根据您的布尔值将其删除。
  • 我将撤销我在之前评论中提到的内容,因为我记得 Angular 的样式设置方式是避免全局样式和更多的隔离,如果这是任何其他应用程序,那么我会去我之前说的。您的应用程序缺少的是状态管理。如果您让我们说 redux 来存储您的应用程序状态,那么您可以获得关于何时在任何组件上设置深色主题的布尔值。将它与 [ngClass] 一起使用,你应该很高兴。
  • 您好,您对状态管理的看法是完全正确的。我设法找到了为什么它没有显示黑色的问题。在我取出 home 组件的 HTML 和 Body 标签后,它起作用了。在发现没有标签的其他组件能够在明暗之间切换后,我认为这与 html 和 body 标签存在有关。现在我只是想知道如何进行状态管理,因为在切换选项卡后布尔值设置回 false,这会将布尔值设置回默认值。谢谢!
【解决方案2】:

查看我为这个问题创建的 Stackblitz https://stackblitz.com/edit/angular-ivy-prkazr

app.component.ts:

import { Component, ViewEncapsulation } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class AppComponent {
  setMode = false;

  receiveMode($event) {
    this.setMode = $event;
    console.log("MODEEEE", this.setMode);
  }
}

您需要在 app.component 装饰中使用 encapsulation: ViewEncapsulation.ShadowDom 才能在其子组件中使用父样式,请参阅 https://angular.io/api/core/ViewEncapsulation,这是因为 ::ng-deep 已弃用,请参阅 https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep 了解更多信息。

app.component.html

<div id="main-container" [ngClass]="[setMode ? 'darkTheme' : '']">

    <app-header (mode)="receiveMode($event)"></app-header>

    <router-outlet></router-outlet>

</div>

app.component.css

#main-container{
  width: 100%;
  min-height: 100vh;
}

#main-container.darkTheme {
  background-color: #000;
}

#main-container.darkTheme h1{
 color: white;
}

#main-container.darkTheme nav{
 background-color: #fafafa;
}

#main-container.darkTheme .nav-link{
 color: #000;
}

#main-container.darkTheme .nav-link.is-active{
 color: #cb2d67;
}

header.component.html

<nav>
    <a routerLink="/" routerLinkActive="is-active" [routerLinkActiveOptions]="{exact: true}" class="nav-link" tabindex="1">
        Home
    </a>
    <a routerLink="/about" routerLinkActive="is-active" [routerLinkActiveOptions]="{exact: true}" class="nav-link" tabindex="1">
        About
    </a>

  <button (click)="onChangeToggle()">Toggle Theme</button>
</nav>

【讨论】:

  • 感谢您的回复。但是我试过了,还是不行
猜你喜欢
  • 2017-07-17
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
  • 2021-08-12
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多