【问题标题】:Angular 2/4 How to style angular material design snackbarAngular 2/4 如何设置 Angular Material Design 小吃吧的样式
【发布时间】:2017-08-01 13:31:26
【问题描述】:

我是 Angular2/4 和 Angular 打字稿的新手。我想为角形材料设计 snackbar 设置样式,例如将背景颜色从黑色和字体颜色更改为其他颜色。
我该如何设计“snackbar”的样式?

我在服务/核心中有材料设计小吃栏,为了使其可用,我根据需要在每个组件中调用它。

如何在 Angular 2/4 中设置 Angular 2 材料设计“snackbar”的样式?我在下面包含了代码 sn-p:

服务/核心

import { Injectable, Inject } from '@angular/core';
import { Observable } from 'rxjs/Observable'
import { DOCUMENT } from'@angular/platform-browser'; 
import { MdDialog, MdDialogRef } from '@angular/material'; 
import { MdDialogConfig, ComponentType } from '@angular/material'; 
import {MdSnackBar} from '@angular/material';

constructor(
    public dialog: MdDialog,
    public snackBar: MdSnackBar,
    @Inject(DOCUMENT) public doc: any   ) {
      dialog.afterOpen.subscribe((ref: MdDialogRef<any>) => {
        if (!doc.body.classList.contains('no-scroll')) {
        doc.body.classList.add('no-scroll');
        }
      });
      dialog.afterAllClosed.subscribe(() => {
        doc.body.classList.remove('no-scroll');
      });        }

   openSnackBar(message: string, action?: string) {
    this.snackBar.open(message, action, {
      duration: 4000,
    });   }

wiz.components.ts ....

 saveData(): void {
    this.advisorClientModel.currentStep = this.currentStep;
    this.advisorClientModel.clientId = this.faService.getClientId();
    this.advisorClientModel.isMaxAmount = this.isMaximumAmount;
    this.advisorClientModel.desiredLoanAmount = this.loanAmount;
    this.advisorClientModel.maxLoanAmount = this.eligibleSelected.advanceAmount;
    this.advisorClientModel.pledgedAccounts = this.getPledgedAccountsArray();
    this.advisorClientModel.pledgedMarketValue = this.getPledgedMarkeValue();

    this.faService.updateAdvisorClient( this.advisorClientModel )
      .subscribe(
        successModel => {
          this.coreService.openSnackBar("Your Data Has been Saved");
          this.navigateTo("fa/wiz" + (this.currentStep + 1));
        },
        error => {
          this.onError(error);
        }
      );
  }

【问题讨论】:

    标签: angular angular-material2


    【解决方案1】:

    md-snackbar 提供服务来提供自定义configconfig 的属性之一是 extraClasses,它允许将 CSS 类添加到小吃店容器 (doc)。

    extraClasses 可以与::ng-deep 一起使用来覆盖默认的 CSS 类。这是一个例子:

    component.ts:

    需要在组件中遵循import

    import {MdSnackBar, MdSnackBarConfig} from '@angular/material';
    

    (提供自定义配置)

    openSnackBar(message: string, action?: string) {
      let config = new MdSnackBarConfig();
      config.extraClasses = ['custom-class'];
      this.snackBar.open(message, action ? 'Action Label' : undefined, config);
    }
    

    component.css:

    ::ng-deep snack-bar-container.custom-class {
      background: yellow;
    }
    
    ::ng-deep .custom-class .mat-simple-snackbar {
      color: green;
    }
    

    如果您想尝试,这里是Plunker demo

    2018 年 11 月更新:Angular 6+

    语法发生了一些变化,md- 前缀被替换为 mat-extraClasses 被替换为 panelClass。不过功能总体上是一样的:

    const config = new MatSnackBarConfig();
    config.panelClass = ['custom-class'];
    ...
    

    还有进口:

    import { MatSnackBar, MatSnackBarConfig } from '@angular/material';
    

    【讨论】:

    • 非常感谢!旁注:所有这些“Md...”的东西都被重命名为“Mat...”。例如MatSnachBarConfig.
    • extraClasses 现在已弃用。请改用panelClass
    • 另外,如果你需要改变动作按钮的颜色,试试这个::ng-deep .custom-class .mat-simple-snackbar-action { color: green; }
    • 如果 Snackbar 在服务中怎么办?如何从服务中调用样式?
    【解决方案2】:

    我编写了以下代码来使用 Angular 6 和 Angular Material 6。

    包含snackBar调用的服务:

    @Injectable()
    export class MessageService {
       constructor(private snackBar: MatSnackBar) {}
    
       showError(message: string) {
          const config = new MatSnackBarConfig();
          config.panelClass = ['background-red'];
          config.duration = 5000;
          this.snackBar.open(message, null, config);
       }
    }
    

    styles.css 文件中添加 css 类:

    .background-red{
       background-color: rgb(153, 50, 50);
    }
    

    【讨论】:

    • 它只是一个控制变量。不开两个进度是必须的,不过这个不在这个sn-p里,可以忽略。我会将它从 sn-p 中删除。
    • 我是这么认为的。这就是我问的原因,所以你可以删除。而且还少了一个“;”在 config.duration 行之后。
    • 感谢您的观察,我已修复它。
    • 我必须使用 .mat-snack-bar-container.background-red 类,否则 .background-red 类会被覆盖。
    • 我将 !important 添加到 styles.css 中的所有内容以使其正常工作
    【解决方案3】:

    从mat SnackBarConfig Class你可以添加

    panelClass: string | string[]

    “要添加到小吃店容器的额外 CSS 类”。

    this.snackBar.open("Your custom Message", '', {
          panelClass:"custom_sneak_bar"
    }
    

    【讨论】:

      【解决方案4】:

      Angular 5 及更高版本您不需要使用自定义配置服务,只需在方法 openFromComponent 的持续时间后传递 extraClasses 数组即可。

      方法如下

      app.module.ts

        import { MatSnackBarModule } from '@angular/material';
      

      添加到导入

      @NgModule({ declarations: [ .. ], imports: [ MatSnackBarModule ].... 
      

      component.ts

      需要在组件中进行以下导入:

      import { MatSnackBar } from '@angular/material';
      

      调用SnackBar的示例方法

      openSnackBar(message, type) {
         let extraClasses;
         if (type == 'error') {
           extraClasses = ['background-red'];
         } else {
           extraClasses = ['background-green'];
       }
      
       this.snackBar.openFromComponent(SnackBarTemplateComponent, {
         duration: 30000,
         extraClasses: extraClasses,
         data: {
           message: message,
           type:type
         }
       });
      }
      

      将相应的类添加到全局 style.css 样式.css:

      .background-red{
        background-color: rgb(153, 50, 50);
      }
      .background-green{
        background-color: rgb(29, 102, 29);
      }
      

      【讨论】:

      • 我必须在样式中添加 !important。有效!
      【解决方案5】:

      对于角度 6 到 9 的作品(在您的全局 scss 样式中)

      说明:使用@mixin 函数自定义您的snackingBar,在这种情况下称为“@mixinsnack-theme($theme)”,然后您将在此函数中声明的所有类添加到您的模板中,如下所示

      @include snack-theme($my-app-theme);

      全局scss文件(styles.scss):

      @import '../node_modules/@angular/material/_theming.scss';
      @include mat-core();
      
      $background-primary: #232323;
      $background-accent: #353535;
      $background-warn: #c1640c;
      $font-color-default: silver;
      
      $my-app-primary: mat-palette($mat-light-green, 700);
      $my-app-accent: mat-palette($mat-cyan, 800 );
      $my-app-warn: mat-palette($mat-red, 400);
      
      
      $my-app-theme: mat-dark-theme($my-app-primary, $my-app-accent, $my-app-warn);
      
      
      @mixin snack-theme($theme) {
          // Extract whichever individual palettes you need from the theme.
          $primary: map-get($theme, primary);
          $accent: map-get($theme, accent);
          $warn: map-get($theme, warn);
      
      
          .mat-snack-bar-container {
              background-color: $background-accent !important;
              color: $font-color-default;
          }
          //Added with panelClass property
          .snack-error {
              button {
                  color: mat-color($warn)
              }
          }
          //Added with panelClass property
          .snack-success {
              button {
                  color: mat-color($primary)
              }
          }
      }
      
      @include snack-theme($my-app-theme);
      
      ...
      

      并且像(在你的组件中)一样调用零食

              this.snackBar.open("your message", 
                 "your action",
                {
                  duration: 3000,
                  panelClass: (isSuccess ? ["snack-success"] : ["snack-error"])
                })
      

      snack-success 和snack-error 类在@mixed 函数(@mixinsnack-theme)中定义

      注意:不要忘记在你的 scss 组件中包含你的全局 scss 文件。 例如:

      【讨论】:

      • 请考虑在您的答案中添加解释
      【解决方案6】:

      ::ng-deep 支持将被取消,正如即将宣布的那样。在您的消息栏组件上设置 encapsulation: ViewEncapsulation.None,您就可以开始了:

      import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
      import { MAT_SNACK_BAR_DATA } from '@angular/material';
      import { MessageBarType } from './message-bar.model';
      
      @Component({
        selector: 'app-message-bar',
        templateUrl: 'message-bar.component.html',
        styleUrls: ['message-bar.component.scss'],
        encapsulation: ViewEncapsulation.None
      })
      export class MessageBarComponent implements OnInit {
      
        public MessageBarType: typeof MessageBarType = MessageBarType;
      
        constructor(@Inject(MAT_SNACK_BAR_DATA) public data: { text: String, type: MessageBarType }) { }
      
        ngOnInit() {
        }
      }
      

      然后在你的 scss 文件中:

      @import '~@angular/material/theming';
      @import '~app/theme-defs';
      
      snack-bar-container {
        &.error {
          background-color: mat-color($warn);
        }
      
        &.warning {
          background-color: mat-color($dark-warn);
        }
      
        &.info {
          background-color: mat-color($accent);
        }
      }
      

      【讨论】:

        【解决方案7】:

        (目前 Angular 9) 嗨,这是底部两个链接的摘要。 你在这里得到了带有 css 类和变量的调用函数,以及在snackBar 组件中获取它们的值的方法。希望这会有所帮助

        在你想增加一个snackBar的组件中,“父组件”:

        import {
          MatSnackBar
        } from '@angular/material/snack-bar';
        import {
          SnackBarComponent
        } from '../../../shared/snack-bar/snack-bar.component';
        
        
        @Component({
          selector: 'app-father-component',
          templateUrl: './father-.component.html',
          styleUrls: ['./father-editor.component.scss'],
        })
        export class FatherComponent implements OnInit {
        
          private _durationInSeconds = 5;
        
          get durationInSeconds(): number {
            return this._durationInSeconds;
          }
        
          set durationInSeconds(value: number) {
            this._durationInSeconds = value;
          }
        
          private _className: string;
        
          get className(): string {
            return this._className;
          }
        
          set className(value: string) {
            this._className = value;
          }
        
          private _mMessage: string;
        
          get mMessage(): string {
            return this._mMessage;
          }
        
          set mMessage(value: string) {
            this._mMessage = value;
          }
        
          constructor(
            private snackBar: MatSnackBar
          ) {}
        
          ngOnInit(): void {
        
            // your onInit code
          }
        
        // Calling that function rises the snackBar, from .ts this.openSnackBar()
        // From template event <button (click)="openSnackBar()"></button> etc...
        // No needs to insert the <app-snack-bar> tag in the template.
        
          openSnackBar() {
            this.snackBar.openFromComponent(SnackBarComponent, {
              duration: this.durationInSeconds * 1000,
              data: {
                myMessage: this.mMessage,
                antoherVar: 'antoher message'
              },
              // here this.className is a string which value is a Bulma class 'has-text-info', snackbar automatically uses the value from panelClass
              panelClass: this.className
            });
          }

        然后是snackBar itSelf组件,即“子组件”:

        import {
          Component,
          Inject,
          OnInit
        } from '@angular/core';
        import {
          MAT_SNACK_BAR_DATA
        } from '@angular/material/snack-bar';
        
        @Component({
          selector: 'app-snack-bar',
          templateUrl: './snack-bar.component.html',
          styleUrls: ['./snack-bar.component.scss'],
        })
        export class SnackBarComponent implements OnInit {
        
          myMessage: string;
          antoherVar: string;
        
          constructor(
            @Inject(MAT_SNACK_BAR_DATA) public data: any
          ) {
          // there you get the datas you have passed to the snackbar through the openSnackBar function in the father-component, setting up local properties to their values
            this.myMessage = data.myMessage;
            this.antoherVar = data.antoherVar;
          }
        
          ngOnInit(): void {}
        
        }
        <!--Here we use the local variable set with the datas passed through the data object -->
        <!--No needs to setup a class to use the panelClass value passed, it is automatic -->
        <span>{{ myMessage }}</span>

        【讨论】:

          猜你喜欢
          • 2018-07-03
          • 2018-09-12
          • 1970-01-01
          • 2018-01-06
          • 2016-09-20
          • 1970-01-01
          • 1970-01-01
          • 2017-06-08
          • 1970-01-01
          相关资源
          最近更新 更多