Angular Event Emiting更改材质主题

时间:2020-04-29 01:30:50

标签: angular-material angular9

请通过选择显示图像的一种颜色来更改应用程序的主题。 我具有以下组件:

  • 标题组件(路径:'src / app / shared / components / header')
  • 默认组件(路径:“ src / app / layouts / default”)

    下图是包含标题组件的默认组件。

Image showing theme colors to be selected for my angular app

header.component.html

    <mat-toolbar color="primary">
  <mat-toolbar-row>
    <button mat-icon-button (click)="toggleSideBar()">
      <mat-icon>menu</mat-icon>
    </button>

    <span>APP LOGO</span>

    <div fxFlex fxLayout="row" fxLayoutAlign="flex-end">
      <ul fxLayout="row" fxLayoutGap="20px">
        <li>
          <button mat-icon-button [matMenuTriggerFor]="theme">
            <mat-icon>format_color_fill</mat-icon>
          </button>
          <mat-menu #theme="matMenu">
            <div class="btn-wrapper">
              <button mat-mini-fab class="btn btn-default" (click)="selectedTheme='default'"></button>
              <button mat-mini-fab class="btn btn-purple" (click)="selectedTheme='purple'"></button>
              <button mat-mini-fab class="btn btn-pink" (click)="selectedTheme='pink'"></button>
              <button mat-mini-fab class="btn btn-deep-orange" (click)="selectedTheme='deep-orange'"></button>
            </div>
          </mat-menu>
        </li>
        <li>
          <button mat-icon-button>
            <mat-icon>settings</mat-icon>
          </button>
        </li>
        <li>
          <button mat-button [matMenuTriggerFor]="menu">
            <mat-icon>person_outline</mat-icon>
          </button>
          <mat-menu #menu="matMenu">
            <button mat-menu-item>
              <mat-icon>exit_to_app</mat-icon>
              Sign out
            </button>
          </mat-menu>
        </li>
      </ul>
    </div>
  </mat-toolbar-row>
</mat-toolbar>

header.component.ts

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

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

  @Output() toggleSideBarForMe: EventEmitter<any> = new EventEmitter();
  @Output() selectedTheme: string;

  constructor() { }

  ngOnInit(): void {
  }

  toggleSideBar(){
    this.toggleSideBarForMe.emit();
    setTimeout(() => {
      window.dispatchEvent(
        new Event('resize')
      );
    }, 300);
  }

}

default.component.html

    <div [ngClass]="selectedTheme">
  <app-header (toggleSideBarForMe)="toggle()"></app-header>

  <mat-drawer-container>
    <mat-drawer mode="side" [opened]="sideBarOpen">
      <app-sidebar></app-sidebar>
    </mat-drawer>
    <mat-drawer-content>
      <router-outlet></router-outlet>
    </mat-drawer-content>
  </mat-drawer-container>
  <app-footer></app-footer>
</div>

default.component.ts

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

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

  sideBarOpen = true;

  constructor() {
  }

  ngOnInit(): void {
  }

  toggle(){
    this.sideBarOpen = !this.sideBarOpen;
  }
}

这是我的自定义主题文件: custom-theme.scss

    @import '~@angular/material/theming';
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$my-app-primary: mat-palette($mat-indigo);
$my-app-accent:  mat-palette($mat-pink);

// The warn palette is optional (defaults to red).
$my-app-warn:    mat-palette($mat-red);

// Create the theme object (a Sass map containing all of the palettes).
$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent, $my-app-warn);

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($my-app-theme);

.alternate-teal-theme {
  $teal-app-primary: mat-palette($mat-teal);
  $teal-app-accent:  mat-palette($mat-yellow);

  // The warn palette is optional (defaults to red).
  $teal-app-warn:    mat-palette($mat-red);

  // Create the theme object (a Sass map containing all of the palettes).
  $teal-app-theme: mat-light-theme($teal-app-primary, $teal-app-accent, $teal-app-warn);

  // Include theme styles for core and each component used in your app.
  // Alternatively, you can import and @include the theme mixins for each component
  // that you are using.
  @include angular-material-theme($teal-app-theme);
}

.purple {
  $purple-primary: mat-palette($mat-purple);
  $purple-accent: mat-palette($mat-light-green);
  $purple-theme: mat-light-theme($purple-primary, $purple-accent);
  @include angular-material-theme($purple-theme);
}
.pink {
  $pink-primary: mat-palette($mat-pink);
  $pink-accent: mat-palette($mat-yellow);
  $pink-theme: mat-light-theme($pink-primary, $pink-accent);
  @include angular-material-theme($pink-theme);
}

.deep-orange {
  $deep-orange-primary: mat-palette($mat-deep-orange);
  $deep-orange-accent: mat-palette($mat-teal, A100);
  $deep-orange-theme: mat-light-theme($deep-orange-primary, $deep-orange-accent);
  @include angular-material-theme($deep-orange-theme);
}

请问如何使所选主题在应用上生效?

1 个答案:

答案 0 :(得分:0)

custom-theme.scss文件的内容应该传递或导入到您的style.scss中。为了使主题影响整个应用程序,您必须在div中声明相同类的CSS,该div包含boostrap组件的html内容。我在您的代码中注意到的错误是,在文件header.component.ts中selectedTheme的输出未发出任何事件,您应像这样@Output() selectedTheme: EventEmitter<string> = new EventEmitter<string>();进行声明,这里我为您提供了一个有效的示例我刚才解释的所有内容:stackblitz