Angular 2/4如何设计棱角分明的材料设计

时间:2017-08-01 13:31:27

标签: angular angular-material2

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

我在服务/核心中有材料设计零食栏,并且可以根据需要在每个组件中调用它。

如何在Angular 2/4中设置Angular 2材质设计" snackbar"的样式?我在下面添加了代码段:

服务/芯

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);
        }
      );
  }

7 个答案:

答案 0 :(得分:36)

md-snackbar提供了一项提供自定义config的服务。 config的一个属性是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

NOV 2018更新:Angular 6 +

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

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

和进口也是:

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

答案 1 :(得分:6)

我制作了以下代码来处理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);
}

答案 2 :(得分:3)

从席SnackBarConfig Class您可以添加

panelClass: string | string[]

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

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

答案 3 :(得分:1)

Angular 5及以上版本,你不需要使用自定义配置服务,只需在方法openFromComponent的持续时间之后传递extraClasses数组。

以下是

的方法

<强> app.module.ts

override func viewDidLoad() {
        super.viewDidLoad()

        do {

            let documentDirectory = getDocumentsDirectory()

            let fileURL = documentDirectory.appendingPathComponent("10xFile.pdf")

            let dataFromURL = try Data(contentsOf: location!)
            try dataFromURL.write(to: fileURL, options: [])

        } catch {
            print(error)
        }

    }

    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let documentsDirectory = paths[0]
        return documentsDirectory
    }

    @IBAction func actionButtonPressed(_ sender: Any) {

        let documentsDir = getDocumentsDirectory()

        let fileURL = documentsDir.appendingPathComponent("10xFile.pdf")

        let ac = UIActivityViewController(activityItems: [fileURL], applicationActivities: nil)

        self.present(ac, animated: true)
    }

添加到导入

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

<强> component.ts

需要在组件中导入:

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

调用SnackBar的示例方法

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

将相应的类添加到global style.css style.css中:

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
   }
 });
}

答案 4 :(得分:1)

与6/7角钢配合使用(在您的材料的全局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"])
          })

答案 5 :(得分:0)

:: ng-deep 支持将被删除,如同很快宣布的那样。在消息栏组件上设置封装: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);
  }
}

答案 6 :(得分:0)

(目前为角度9) 嗨,这是底部两个链接的摘要。 您可以在此处获得带有css类和传递的变量的调用函数,以及在快餐栏组件中获取其值的方法。希望对您有帮助

在您希望升起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
    });
  }

然后是小吃栏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>