【问题标题】:Trying to lazy load custom themes dynamically based on angular material尝试根据角度材料动态延迟加载自定义主题
【发布时间】:2021-09-01 18:00:11
【问题描述】:

我正在用 Angular 材料编写一个 Angular 12 网站。 该项目支持多个域,并且在不同的域上它应该显示不同的主题。

所以我在这里要解决的是能够通过延迟加载动态加载主题。

我的自定义主题有效.. 基本的角度材质功能无效,但我确实收到了消息

Could not find Angular Material core theme. Most Material components may not work as expected. For more info refer to the theming guide: https://material.angular.io/guide/theming

我搜索了很多,如果我正确加载 css 文件并将其附加到头部,它应该可以正常工作。

好的..所以首先..

我创建了 app/themes 目录

我有 3 个主题,windy.scsswindy-car.scsswindy-shop.scss,每个主题都需要 common.scss

我有几个组件使用我在每个文件中创建的具有特定颜色的变量,common.scss 实际上在选择颜色时装饰组件。

例如:

common.js 包括:

app-root {

  div#my-mat-drawer {
    background: $container-bg;
  }

}

windy.scss 包含:

$container-bg:  #aabbcc;

我将展示一个 scss 文件作为示例,当我只使用一个主题时它可以工作,所以我知道格式很好。

这是windy.scss

@use '../../node_modules/@angular/material/index' as mat;
$container-bg:  #aabbcc;
$container-color:  white;

$button1-color: #ccdd99;
$button2-color: #112233;

$product-card-text: red;

$category-title-bg: blue;

$product-categories-bg: yellow;

$toolbar-bg-color: green;

$dark-primary-text: rgba(black, 0.87);
$dark-secondary-text: rgba(black, 0.54);
$dark-disabled-text: rgba(black, 0.38);
$dark-dividers: rgba(black, 0.12);
$dark-focused: rgba(black, 0.12);
$light-primary-text: white;
$light-secondary-text: rgba(white, 0.7);
$light-disabled-text: rgba(white, 0.5);
$light-dividers: rgba(white, 0.12);
$light-focused: rgba(white, 0.12);

$my-cyan-palette: (
  50: #e0f7fa,
  100: #b2ebf2,
  200: #80deea,
  300: #4dd0e1,
  400: #26c6da,
  500: #00bcd4,
  600: #00acc1,
  700: #0097a7,
  800: #00838f,
  900: $button2-color,
  A100: #84ffff,
  A200: #18ffff,
  A400: #00e5ff,
  A700: #00b8d4,
  contrast: (
    50: $dark-primary-text,
    100: $dark-primary-text,
    200: $dark-primary-text,
    300: $dark-primary-text,
    400: $dark-primary-text,
    500: $light-primary-text,
    600: $light-primary-text,
    700: $light-primary-text,
    800: $light-primary-text,
    900: $light-primary-text,
    A100: $dark-primary-text,
    A200: $dark-primary-text,
    A400: $dark-primary-text,
    A700: $dark-primary-text,
  )
);

$my-lime-palette: (
  50: #f9fbe7,
  100: #f0f4c3,
  200: #e6ee9c,
  300: #dce775,
  400: #d4e157,
  500: #cddc39,
  600: #c0ca33,
  700: #afb42b,
  800: #9e9d24,
  900: $button1-color,
  A100: #f4ff81,
  A200: #eeff41,
  A400: #c6ff00,
  A700: #aeea00,
  contrast: (
    50: $dark-primary-text,
    100: $dark-primary-text,
    200: $dark-primary-text,
    300: $dark-primary-text,
    400: $dark-primary-text,
    500: $dark-primary-text,
    600: $dark-primary-text,
    700: $dark-primary-text,
    800: $dark-primary-text,
    900: $light-primary-text,
    A100: $dark-primary-text,
    A200: $dark-primary-text,
    A400: $dark-primary-text,
    A700: $dark-primary-text,
  )
);



$windy-store-primary: mat.define-palette($my-cyan-palette, 900);
$windy-store-accent: mat.define-palette($my-lime-palette,900); 
$windy-store-warn: mat.define-palette($my-cyan-palette,900);

 $windy-store-theme: mat.define-light-theme((
  color: (
    primary: $windy-store-primary,
    accent: $windy-store-accent,
    warn: $windy-store-warn,
  )
));

@include mat.all-component-themes($windy-store-theme);
@import "common";

现在.. 在 angular.json 中,我用inject: false 添加了这些文件:

"styles": [
              "src/styles.scss",
              {
                "input": "src/themes/windy.scss",
                "bundleName": "windy",
                "inject": false
              },
              {
                "input": "src/themes/windy-car.scss",
                "bundleName": "windy-car",
                "inject": false
              },
              {
                "input": "src/themes/windy-shop.scss",
                "bundleName": "windy-shop",
                "inject": false
              }
            ]

我创建了一个 style-manager 服务和一个 theme.service 并将它们添加到 app.module.ts 中的提供程序。

style-manager-service.ts

/**
 * Copied from https://github.com/angular/material.angular.io/blob/master/src/app/shared/style-manager/style-manager.ts
 */

import { Injectable } from "@angular/core";

@Injectable()
export class StyleManagerService {
  constructor() {}

  /**
   * Set the stylesheet with the specified key.
   */
  setStyle(key: string, href: string) {
    getLinkElementForKey(key).setAttribute("href", href);
  }

  /**
   * Remove the stylesheet with the specified key.
   */
  removeStyle(key: string) {
    const existingLinkElement = getExistingLinkElementByKey(key);
    if (existingLinkElement) {
      document.head.removeChild(existingLinkElement);
    }
  }
}

function getLinkElementForKey(key: string) {
  return getExistingLinkElementByKey(key) || createLinkElementWithKey(key);
}

function getExistingLinkElementByKey(key: string) {
  return document.head.querySelector(
    `link[rel="stylesheet"].${getClassNameForKey(key)}`
  );
}

function createLinkElementWithKey(key: string) {
  const linkEl = document.createElement("link");
  linkEl.setAttribute("rel", "stylesheet");
  linkEl.setAttribute("type", "text/css");
  linkEl.classList.add(getClassNameForKey(key));
  document.head.appendChild(linkEl);
  return linkEl;
}

function getClassNameForKey(key: string) {
  return `app-${key}`;
}

theme.service.ts

import { Injectable } from "@angular/core";

import { StyleManagerService } from "./style-manager.service";

@Injectable()
export class ThemeService {
  constructor(
    private styleManager: StyleManagerService
  ) {}


  setTheme(themeToSet: string) {
    this.styleManager.setStyle(
      "theme",
      `${themeToSet}.css`
    );
  }
}

我将private readonly themeService: ThemeService 注入app.component.ts 并在构造函数中运行this.themeService.setTheme('windy-car');

和结果.. 我确实看到了所选主题的自定义颜色,但角材料功能被破坏了。 color=primary 不起作用,并且其他与角度材质相关的样式不显示。

例如在工具栏中我有color="primary",但颜色仍然是白色。

我确定这与错误 Could not find Angular Material core theme. Most Material components may not work as expected. For more info refer to the theming guide: https://material.angular.io/guide/theming 有关,但我不知道如何解决。

有什么想法吗?

** 更新 1 **

当我在styles.scss 中添加以下内容时:

@import '~@angular/material/theming';

@include mat-core();

我仍然得到错误

Could not find Angular Material core theme. Most Material components may not work as expected. For more info refer to the theming guide: https://material.angular.io/guide/theming

角度材质组件可以正常工作,但它完全忽略了我选择的颜色。

【问题讨论】:

    标签: angular sass angular-material theming angular-lazyloading


    【解决方案1】:

    我终于解决了:)

    所以在我添加的主要style.scss 文件中:

    @use '~@angular/material' as mat;
    @import '~@angular/material/theming';
    @include mat.core();
    

    我还添加了一个默认主题,我用我的文件覆盖了它,只是为了不出现“找不到角度材料核心主题”错误

    $a-primary: mat.define-palette(mat.$indigo-palette);
    $a-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
    
    // The warn palette is optional (defaults to red).
    $a-warn: mat.define-palette(mat.$red-palette);
    
    // Create the theme object. A theme consists of configurations for individual
    // theming systems such as "color" or "typography".
    $a-theme: mat.define-light-theme((
      color: (
        primary: $a-primary,
        accent: $a-accent,
        warn: $a-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 mat.all-component-themes($a-theme);
    

    • 更新 - 我实际上删除了那个。我在一瞬间看到了我定义的这个主题,然后它变成了我的懒加载主题。如果我愿意,我可以只改变这个主题来写,这样开关就不会那么糟糕了。但我完全删除了它,除了有这个警告之外,它不会以任何方式影响我的应用程序。

    在我的个人主题样式文件中,我只需要@use '../../node_modules/@angular/material/index' as mat;

    现在在普通 scss 中,我不再直接指向我的组件,而是创建了一个类并将该类名添加到组件中。

    例如:

    代替:

    app-toolbar {
      mat-toolbar {
        background: $toolbar-bg-color;
      }
    }
    

    原来我有很多::ng-deep,但我把它们都删除了,因为我想修改的所有组件都有panelClass属性和我的组件..我只是给了它们一个类名。

    所以我就这么做了:

    .app-toolbar-mat-toolbar {
        background: $toolbar-bg-color;
      }
    

    【讨论】:

      猜你喜欢
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 2018-07-23
      • 2020-10-14
      • 2018-08-16
      相关资源
      最近更新 更多