web-dev-qa-db-ger.com

Themen in eckigem Material wechseln 5

Ich habe einige Artikel dazu gelesen, aber sie scheinen auf verschiedene Weise zu widersprechen. Ich hoffe, dass ich das gleiche Thema erneut erstellen kann, wie die eckige Materialdokumentationsseite für die neueste Version des eckigen Materials [5.0.0-rc0].

Ich habe zwei benutzerdefinierte Themen, dies ist custom-theme.scss, und es gibt light-custom-theme.scss, das fast identisch ist, ohne das Matt-Dunkel-Thema

@import '[email protected]/material/theming';
$custom-theme-primary: mat-palette($mat-blue);
$custom-theme-accent: mat-palette($mat-orange, A200, A100, A400);
$custom-theme-warn: mat-palette($mat-red);
$custom-theme: mat-dark-theme($custom-theme-primary, $custom-theme-accent, $custom-theme-warn);

@include angular-material-theme($custom-theme);

Mein styles.scss sieht so aus

@import '[email protected]/material/theming';
@include mat-core();
@import 'custom-theme.scss';
@import 'light-custom-theme.scss';
.custom-theme {
  @include angular-material-theme($custom-theme);
}

.light-custom-theme {
  @include angular-material-theme($light-custom-theme);
}

Und dann heißt es in der index.html <body class="mat-app-background">

Alles funktioniert gut, wenn ich ein Thema mache. Aber ich versuche zwischen den beiden zu wechseln. Durch Hinzufügen beider Designs zu angle-cli.json wird das Light-Custom-Design übernommen

"styles": [
  "styles.scss",
  "custom-theme.scss",
  "light-custom-theme.scss"
],

Ich habe den folgenden Code in einer meiner Komponenten, um mit dem Umschalten von Themen umzugehen

toggleTheme(): void {
  if (this.overlay.classList.contains("custom-theme")) {
    this.overlay.classList.remove("custom-theme");
    this.overlay.classList.add("light-custom-theme");
  } else if (this.overlay.classList.contains("light-custom-theme")) {
    this.overlay.classList.remove("light-custom-theme");
    this.overlay.classList.add("custom-theme");
  } else {
    this.overlay.classList.add("light-custom-theme");
  }
}

Bei jeder Ausführung bleibt das Thema jedoch gleich. Für das, was es wert ist, gibt es bereits ein "cdk-overlay-container" Objekt an Position 0 in overlay.classList

0:"cdk-overlay-container"
1:"custom-theme"
length:2
value:"cdk-overlay-container custom-theme" 

Ich bin mir nicht sicher, wie ich das debuggen kann, da mir die eckige Materialdokumentation nicht zu viel Arbeit gibt, jede Hilfe wäre dankbar!

Vielen Dank!

7
Surreal

Hier ist eine alternative Lösung für Angular 5.1 +/Angular Material 5.0+.

* Bearbeiten: Wie bereits erwähnt, funktioniert dies immer noch in Angular 7+.

Beispiel für die Bearbeitung eines Editors - https://stackblitz.com/edit/dynamic-material-theming

Fügen Sie in theme.scss ein Standarddesign (beachten Sie, dass es nicht unter einem Klassennamen aufbewahrt wird. Angular verwendet es als Standard) und dann ein helles und dunkles Design.

theme.scss

@import '[email protected]/material/theming';
@include mat-core();

// Typography
$custom-typography: mat-typography-config(
  $font-family: Raleway,
  $headline: mat-typography-level(24px, 48px, 400),
  $body-1: mat-typography-level(16px, 24px, 400)
);
@include angular-material-typography($custom-typography);

// Default colors
$my-app-primary: mat-palette($mat-teal, 700, 100, 800);
$my-app-accent:  mat-palette($mat-teal, 700, 100, 800);

$my-app-theme: mat-light-theme($my-app-primary, $my-app-accent);
@include angular-material-theme($my-app-theme);

// Dark theme
$dark-primary: mat-palette($mat-blue-grey);
$dark-accent:  mat-palette($mat-amber, A200, A100, A400);
$dark-warn:    mat-palette($mat-deep-orange);

$dark-theme:   mat-dark-theme($dark-primary, $dark-accent, $dark-warn);

.dark-theme {
  @include angular-material-theme($dark-theme);
}

// Light theme
$light-primary: mat-palette($mat-grey, 200, 500, 300);
$light-accent: mat-palette($mat-brown, 200);
$light-warn: mat-palette($mat-deep-orange, 200);

$light-theme: mat-light-theme($light-primary, $light-accent, $light-warn);

.light-theme {
  @include angular-material-theme($light-theme)
}

Schließen Sie in der app.component-Datei OverlayContainer aus @ angle/cdk/overlay ein. Hier finden Sie die Dokumentation von Angular https://material.angular.io/guide/theming ; obwohl ihre Implementierung ein wenig anders ist. Bitte beachten Sie, dass ich OverlayModule auch als Import in app.module verwenden musste.

In meiner app.component-Datei habe ich auch @HostBinding('class') componentCssClass; als Variable deklariert, die verwendet wird, um das Design als Klasse festzulegen.

app.component.ts

import {Component, HostBinding } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { OverlayContainer} from '@angular/cdk/overlay';

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

  constructor(public overlayContainer: OverlayContainer) {}

  @HostBinding('class') componentCssClass;

  onSetTheme(theme) {
    this.overlayContainer.getContainerElement().classList.add(theme);
    this.componentCssClass = theme;
  }

}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { HttpClientModule } from '@angular/common/http';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';

import { AppComponent } from './app.component';

import { OverlayModule} from '@angular/cdk/overlay';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
    MatCardModule,
    MatButtonModule,
    OverlayModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

Rufen Sie schließlich die Funktion onSetTheme aus Ihrer Ansicht auf.

app.component.html

<button mat-raised-button color="primary" (click)="onSetTheme('default-theme')">Default</button>
<button mat-raised-button color="primary" (click)="onSetTheme('dark-theme')">Dark</button>
<button mat-raised-button color="primary" (click)="onSetTheme('light-theme')">Light</button>

Sie könnten ein Observable verwenden, um die Funktionalität dynamischer zu gestalten.

17
K. Waite

Sie müssen die getContainerElement-Methode von OverlayContainer verwenden. Hier einige Beispiele:

this.overlay.getContainerElement().classList.add('my-theme');

Für Ihre Style-Dateien empfehle ich dringend, diese Zeile für custom-theme.scss und light-custom-theme.scss zu entfernen (in diesem Fall benötigen Sie sie nur für Ihre Klassen):

@include angular-material-theme($custom-theme); // Remove this line from custom-theme.scss and light-custom-theme.scss

Wenn Sie auch das Design für Ihre App umschalten möchten, sollten Sie dieses wahrscheinlich in derselben toggleTheme-Methode verwenden:

toggleTheme(): void {
  if (this.overlay.classList.contains("custom-theme")) {
    this.overlay.classList.remove("custom-theme");
    this.overlay.classList.add("light-custom-theme");
  } else if (this.overlay.classList.contains("light-custom-theme")) {
    this.overlay.getContainerElement().classList.remove("light-custom-theme");
    this.overlay.classList.add("custom-theme");
  } else {
    this.overlay.classList.add("light-custom-theme");
  }
  if (document.body.classList.contains("custom-theme")) {
    document.body.classList.remove("custom-theme");
    document.body.classList.add("light-custom-theme");
  } else if (document.body.classList.contains("light-custom-theme")) {
    document.body.classList.remove("light-custom-theme");
    document.body.classList.add("custom-theme");
  } else {
    this.overlay.classList.add("light-custom-theme");
  }
}
10
Edric

Unter Bezugnahme auf @ Edric s Lösung

Verwendet lokaler Speicher um das ausgewählte Thema beizubehalten .

Hier ist mein Github Link, wo ich den Arbeitscode aktualisiert habe: ~ Angular Material Theme Changer

Hoffe das ist auch hilfreich.

0
Sourav Dutta

Sie können immer überprüfen, wie der Theme-Picker in https://material.angular.io/ implementiert wird, und einfach das gleiche https://github.com/angular/material.angular.io/tree tun/master/src/app/shared/theme-picker Wenn Sie dies tun, haben Sie die ewige Lösung, denn im Falle von brechenden Änderungen können Sie immer nach Material suchen, um Informationen zu finden.

0
Kuncevič