【问题标题】:Angular - how to theme my own component using mixin?Angular - 如何使用 mixin 为我自己的组件设置主题?
【发布时间】:2019-12-24 07:53:08
【问题描述】:

我创建了一个组件:

message.component.html

<div class="alert">
  <div class="row">
    <!-- add no-gutters to make it narrower -->
    <div class="col-auto align-self-start">
      <!-- or align-self-center -->
      <mat-icon>{{icon}}</mat-icon>
    </div>
    <div class="col">
      <div class="app-message-title">{{title}}</div>
      <div class="app-message-content">
        <ng-content></ng-content>
      </div>
    </div>
  </div>
</div>

message.component.ts

import { Component, OnInit, Input, ElementRef } from '@angular/core';
import { CanColorCtor, mixinColor, CanColor, ThemePalette } from '@angular/material';


// Boilerplate for applying mixins to MessageComponent.
/** @docs-private */
class MessageComponentBase {
  constructor(public _elementRef: ElementRef) { }
}
const _MessageComponentMixinBase: CanColorCtor & typeof MessageComponentBase = mixinColor(MessageComponentBase);


@Component({
  selector: 'app-message',
  templateUrl: './message.component.html',
  styleUrls: ['./message.component.scss']
})
export class MessageComponent extends _MessageComponentMixinBase implements CanColor, OnInit {

  @Input() title: string;
  @Input() icon: string;
  @Input() color: ThemePalette;

  constructor(
    elementRef: ElementRef) {
    super(elementRef);
  }

  ngOnInit() {

  }

}

message.component.css

@mixin app-message-typography($config) {
  .app-message-title {
    font: {
      family: app-font-family($config);
      size: app-font-size($config, body-2);
      weight: 600;
    }

    line-height: app-line-height($config, body-2);
  }

  .app-message-content {
    font: {
      family: app-font-family($config);
      size: app-font-size($config, body-1);
    }
  }
}

@mixin app-message($theme) {
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $warn: map-get($theme, warn);

  .app-message {
    &.mat-primary {
      color: mat-color($primary);
      background-color: mat-color($primary, 0.15);
    }

    &.mat-accent {
      color: mat-color($accent);
      background-color: mat-color($accent, 0.15);
    }

    &.mat-warn {
      color: mat-color($warn);
      background-color: mat-color($warn, 0.15);
    }
  }
}

显示消息.component.html

  <app-message title="Login failed"
               color="warn"
               icon="warning"
               >Test</app-message>

代码编译正确,我可以看到生成的html是正确的:

<app-message _ngcontent-gus-c16="" class="ng-tns-c16-3 mat-warn" color="warn" icon="warning" title="Login failed" _nghost-gus-c20="" ng-reflect-title="Login failed" ng-reflect-icon="warning" ng-reflect-color="warn">
<div _ngcontent-gus-c20="" class="alert">
    <div _ngcontent-gus-c20="" class="row">
        <div _ngcontent-gus-c20="" class="col-auto align-self-start">
            <mat-icon _ngcontent-gus-c20="" class="mat-icon notranslate material-icons mat-icon-no-color" role="img" aria-hidden="true">warning</mat-icon>
        </div>
        <div _ngcontent-gus-c20="" class="col">
            <div _ngcontent-gus-c20="" class="app-message-title">Login failed</div>
            <div _ngcontent-gus-c20="" class="app-message-content">Test</div>
        </div>
    </div>
</div>

但是样式应用不正确,背景和文本应该是橙色(警告颜色)。

如何使用 mixin 将样式应用到我的组件上?

谢谢


编辑:

按照@Jorge Mussato 的建议,我做了一些调整:

主题.scss:

@import './message/message.component.scss';

// Create a theme.
@mixin themes($theme, $config: null) {
  //@include app-message-typography($config); //Not necessary for the moment
  @include app-message-theme($theme);
}

styles.scss

[...]
@import 'src/app/components/themes.scss';
[...]
$primary: ...;
$accent: ..;
$warn: ...;
$theme: mat-light-theme($primary, $accent, $warn);
[...]
@include themes($theme, $typography);

为了确保错误不是来自我的 scss,我更新了 messsage.component.ts:

@mixin app-message-theme($theme) {
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $warn: map-get($theme, warn);

  // I added this :
  :host {
    display: block;
    background-color: green;
  }

  [...]
  }
}

代码编译正确,但我仍然继续在我的组件上应用主题。

【问题讨论】:

  • 您是否在您的styles.scss(或主主题文件)上调用了您的@mixin

标签: angular sass theming scss-mixins


【解决方案1】:

你需要在你的styles.scss(或主主题文件)中声明你的mixin

styles.scss

...
$config: ...;
$theme: ...;

@import 'path-to-file/message.component.scss';

@include app-message-typography($config);
@include app-message($theme);
...

【讨论】:

  • 谢谢,我按照你的建议更新了我的代码,但我仍然没有将 css 应用于我的组件。有什么想法吗?
  • @CedricArnould 你能做一个stackblitz吗?
  • 你在你的 scss 文件上做了@import '~@angular/material/theming'; 你正在使用材质逻辑,对吧?
  • 我在一个 git 项目上推送了当前问题的最后修改:github.com/ranouf/AllInOneV2/tree/AddMailing/src/client
  • 您需要在您的消息组件中导入您的@import '~@angular/material/theming';(抱歉延迟回复)
【解决方案2】:

我找到了解决方案,感谢@Jorge Mussato 的帮助!

在message.component.scss中,做的好是(我把.app-message换成app-message,加了.alert):

@mixin app-message-theme($theme) {
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $warn: map-get($theme, warn);

  app-message {

    &.mat-primary .alert {
      color: mat-color($primary);
      background-color: mat-color($primary, 0.15);
    }

    &.mat-accent .alert {
      color: mat-color($accent);
      background-color: mat-color($accent, 0.15);
    }

    &.mat-warn .alert {
      color: mat-color($warn);
      background-color: mat-color($warn, 0.15);
    }
  }
}

这是提交差异: https://github.com/ranouf/AllInOneV2/commit/115194b8ca8d098718efa855275e203ba6d276ac

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多