gpt4 book ai didi

javascript - Angular Material Snackbar 配置,带有自定义面板类配置,用于错误、成功、警告消息

转载 作者:行者123 更新时间:2023-12-05 02:07:15 24 4
gpt4 key购买 nike

我在我的 Angular 应用程序中创建了一个全局 snackBarService。我想根据消息类型(错误、成功、警告等)自定义 panelClass。我采用的方法是在构造函数中有一个全局配置,这有助于为 snackbar 定义全局样式/配置,并将添加自定义类以根据消息类型更改背景颜色。

SnackBarService.ts

import { Injectable, NgZone } from "@angular/core";
import { MatSnackBar, MatSnackBarConfig } from "@angular/material";

@Injectable({
providedIn: "root",
})
export class SnackbarService {
private config: MatSnackBarConfig;

constructor(private snackbar: MatSnackBar, private zone: NgZone) {
this.config = new MatSnackBarConfig();
this.config.panelClass = ["snackbar-container"];
this.config.verticalPosition = "top";
this.config.horizontalPosition = "right";
this.config.duration = 4000;
}

error(message: string) {
this.config.panelClass = ["snackbar-container", "error"];
this.show(message);
}

success(message: string) {
this.config.panelClass = ["snackbar-container", "success"];
this.show(message);
}

warning(message: string) {
this.config.panelClass = ["snackbar-container", "warning"];
this.show(message);
}

private show(message: string, config?: MatSnackBarConfig) {
config = config || this.config;
this.zone.run(() => {
this.snackbar.open(message, "x", config);
});
}
}

app.scss

.snackbar-container {
margin-top: 70px !important;
color: beige;
&.error {
background-color: #c62828 !important;
}
&.success {
background-color: #2e7d32 !important;
}

&.warning {
background-color: #ff8f00 !important;
}
}

我将从组件中使用这样的服务

this.snackbarService.success("这条消息来自snackbar!!!");

上面的代码完美运行。

但是,

由于panelClass没有.push方法,所以无法添加动态类,因此每次都需要复制全局类像这样 this.config.panelClass = ["snackbar-container", "error"];

 error(message: string) {
this.config.panelClass.push("error"); // this throws error in typescript
this.show(message);
}

有没有更好的办法解决这个问题?

最佳答案

Angular Material 实际上为您提供了一种设置默认配置的 native 方法,因此您无需实例化 MatSnackBarConfig 然后设置其值。在导入 MatSnackBarModule(App/Shared/Material 模块)的模块中,添加以下内容:

import { MatSnackBarModule, MatSnackBarConfig, MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar';

const matSnackbarDefaultConfig: MatSnackBarConfig = {
verticalPosition: 'top',
horizontalPosition: 'right',
duration: 4000,
};

@NgModule({
// ...
providers: [
{
provide: MAT_SNACK_BAR_DEFAULT_OPTIONS,
useValue: matSnackbarDefaultConfig,
},
],
})
export class MaterialModule { }

然后,您可以像这样使用您的服务(我在其中添加了更多的输入,如果您不喜欢它并且不使用 strictNullChecks,请随意删除它们):

import { Injectable, NgZone } from '@angular/core';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';

// I actually recommend that you put this in a utils/helpers folder so you can use reuse it whenever needed
export const coerceToArray = <T>(value: T | T[]): T[] => (
Array.isArray(value)
? value
: [value]
);

@Injectable({
providedIn: 'root',
})
export class SnackbarService {
constructor(private snackbar: MatSnackBar, private zone: NgZone) { }

error(message: string): void {
this.show(message, { panelClass: ['snackbar-container', 'error'] });
}

success(message: string): void {
this.show(message, { panelClass: ['snackbar-container', 'success'] });
}

warning(message: string): void {
this.show(message, { panelClass: ['snackbar-container', 'warning'] });
}

private show(message: string, customConfig: MatSnackBarConfig = {}): void {
const customClasses = coerceToArray(customConfig.panelClass)
.filter((v) => typeof v === 'string') as string[];

this.zone.run(() => {
this.snackbar.open(
message,
'x',
{ ...customConfig, panelClass: ['snackbar-container', ...customClasses] },
);
});
}
}

此外,由于您的公共(public)方法不接受其他配置(例如持续时间),您可以将您的服务缩减为:

import { Injectable, NgZone } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';

// Just add the new required types here and TypeScript will require the public consumer to pass a valid type
export type SnackBarType = 'error' | 'success' | 'warning';

@Injectable({
providedIn: 'root',
})
export class SnackbarService {
constructor(private snackbar: MatSnackBar, private zone: NgZone) { }

show(message: string, type: SnackBarType): void {
this.zone.run(() => {
this.snackbar.open(
message,
'x',
{ panelClass: ['snackbar-container', type] },
);
});
}
}

关于javascript - Angular Material Snackbar 配置,带有自定义面板类配置,用于错误、成功、警告消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61969174/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com