如何在服务上使用 SnackBar 以在 Angular 2 中的每个组件中使用
Posted
技术标签:
【中文标题】如何在服务上使用 SnackBar 以在 Angular 2 中的每个组件中使用【英文标题】:How to use SnackBar on service to use in every component in Angular 2 【发布时间】:2017-08-03 07:35:07 【问题描述】:我有一个可以工作的小吃店,但它只在每个组件上,我想将它添加到我的服务中,所以我将调用它。这是我在component.ts
上的示例
import MdSnackBar, MdSnackBarRef from '@angular/material';
...
export class EmployeeListComponent implements OnInit
public toastRef: MdSnackBarRef<any>;
constructor(private _activatedRoute:ActivatedRoute,private router: Router, private http:PMISHttpService, private toast: MdSnackBar)
ngOnInit()
this.notify('test');
...
notify (text: string)
this.toastRef = this.toast.open(text, null);
setTimeout(() =>
this.toastRef.dismiss();
, 5000);
...
【问题讨论】:
【参考方案1】:如果您希望 SnackBar 在您的整个应用程序中工作,您应该将其放入您的 app.component 并通过服务与其通信。
notification.service.ts:
public notification$: Subject<string> = new Subject();
app.component.ts:
constructor(
private notificationService: NotificationService, private snackBar: MatSnackBar
)
this.notificationService.notification$.subscribe(message =>
this.snackBar.open(message);
);
任何.component.ts:
this.notificationService.notification$.next('this is a notification');
【讨论】:
通知功能放在哪里?对不起,我是新手 你创建了一个全局服务,它有一个 'subj_notification' rxjs 主题,你的 app.component 有snackBar 并且订阅了'subj_notification'。此时,您应用中的任何组件都可以调用服务的 subj_notification.next() 并且您的应用组件将收到主题更改的通知。【参考方案2】:要让它无处不在,请为它创建一个服务。你也应该使用snackbar config来设置持续时间并将snackbar公开:
import Injectable, NgZone from '@angular/core';
import MatSnackBar from '@angular/material';
@Injectable()
export class CustomSnackbarService
constructor(
public snackBar: MatSnackBar,
private zone: NgZone
)
public open(message, action = 'success', duration = 50000)
this.zone.run(() =>
this.snackBar.open(message, action, duration );
);
还需要在ngZone
:https://github.com/angular/material2/issues/9875中运行
然后在组件中:
customSnackbarService.open('hello')
【讨论】:
这对我很有用!我只是做了一个小修改,让调用者可以访问 SnackBarRef: return this.zone.run(() => return this.snackBar.open(message, action, duration ); );跨度> 有意思,zone.run
是否返回内部函数?
不确定是否仍需要 NgZone
。我试过没有,代码似乎仍然可以工作(使用 Angular 10)。无论如何,感谢您的解决方案!
很有可能【参考方案3】:
您可以轻松做到这一点。请在下面找到我在我的一个项目中使用的示例的示例,它工作得很好
import Injectable from '@angular/core';
import
MatSnackBar,
MatSnackBarConfig,
MatSnackBarHorizontalPosition,
MatSnackBarVerticalPosition,
MatSnackBarRef
from '@angular/material';
@Injectable()
export class SnackBarService
snackBarConfig: MatSnackBarConfig;
snackBarRef: MatSnackBarRef<any>;
horizontalPosition: MatSnackBarHorizontalPosition = 'center';
verticalPosition: MatSnackBarVerticalPosition = 'top';
snackBarAutoHide = '1500';
constructor(private snackBar: MatSnackBar)
openSnackBar(message)
this.snackBarConfig = new MatSnackBarConfig();
this.snackBarConfig.horizontalPosition = this.horizontalPosition;
this.snackBarConfig.verticalPosition = this.verticalPosition;
this.snackBarConfig.duration = parseInt(this.snackBarAutoHide, 0);
this.snackBarConfig.panelClass = 'custom-snackbar';
this.snackBarRef = this.snackBar.open(message, '', this.snackBarConfig);
现在,你只需要在你的组件或者你想使用它的地方注入这个服务,然后调用 openSnackBar() 方法来显示你想要显示的消息。
希望这会有所帮助!
【讨论】:
简单明了的答案【参考方案4】:这是我的工作示例(Angular 11,Angular Material 11.0.1)。
最重要的部分是在 app.module.ts 中包含 MatSnackBarModule。另外,不要忘记导入 BrowserAnimationsModule。
import MatSnackBarModule from '@angular/material/snack-bar';
import BrowserAnimationsModule from '@angular/platform-browser/animations';
@NgModule(
imports: [
MatSnackBarModule,
BrowserAnimationsModule
...
],
那么,我的服务是这样的
import Injectable from '@angular/core';
import MatSnackBar from '@angular/material/snack-bar';
@Injectable(
providedIn: 'root'
)
export class SnackbarService
constructor(
private _snackBar: MatSnackBar)
error(message: string)
return this._snackBar.open(message, undefined, panelClass: ['snackbar-error']);
success(message: string)
return this._snackBar.open(message, undefined, panelClass: ['snackbar-success']);
info(message: string)
return this._snackBar.open(message, undefined, panelClass: ['snackbar-info']);
为了定义样式,我将这些添加到 styles.scss
.mat-simple-snackbar
font-size: 1.2em;
color: white;
.snackbar-error
background-color: red;
.snackbar-success
background-color: green;
.snackbar-info
background-color: blue;
这样,我现在可以从代码中的任何位置(包括来自其他模块的组件)调用 SnackBar。使用示例:
import Component from '@angular/core';
import AuthService from 'src/app/services/auth/auth.service';
import SnackbarService from 'src/app/services/snackbar.service';
@Component(
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
)
export class LoginComponent
loginForm: any;
constructor(private authService: AuthService, private snackbar: SnackbarService)
onSubmit()
this.authService.login(this.loginForm).subscribe(res =>
this.snackbar.success('Logged in');
, e =>
this.snackbar.error('Login failed');
);
【讨论】:
与 Angular 10 和 Angular Material 完美配合 ^10.2.7 您可以升级具有额外属性的小吃栏,例如 5 秒后消失,或者将酒吧从下到上重新定位,如下所示:error(message: string) return this._snackBar.open(message, null, duration: 5000, verticalPosition: 'top', horizontalPosition: 'center', panelClass: ['snackbar-error'] );
很好的答案,你应该使用undefined
而不是null
!
@andrèscoronado 为什么是undefined
?
@TomasLukac typescript (method) MatSnackBar.open(message: string, action?: string | undefined, config?: MatSnackBarConfig<any> | undefined): MatSnackBarRef<TextOnlySnackBar>
@TomasLukac 的非常好的和简单的回答我添加了额外的参数来自动关闭小吃店 panelClass: ['snackbar-info'], duration: 5000
【参考方案5】:
我正在使用版本 version": "2.0.0-beta.10", 这就是我为使其正常工作所做的工作
在 ApModule 中
import NotificationService from "./notification/notification.service";
import MdSnackBarModule from "@angular/material";
@NgModule(
imports: [
MdSnackBarModule,
FormsModule
],
providers: [WebService, NotificationService]
按照上一篇文章的建议创建通知服务
import Injectable from "@angular/core";
import
MdSnackBar,
MdSnackBarConfig,
// MdSnackBarHorizontalPosition,
// MdSnackBarVerticalPosition,
MdSnackBarRef
from "@angular/material";
@Injectable()
export class NotificationService
private snackBarConfig: MdSnackBarConfig;
private snackBarRef: MdSnackBarRef<any>;
private snackBarAutoHide = "5000"; //milliseconds for notification , 5 secs
constructor(private sb: MdSnackBar)
openSnackBar(message)
this.snackBarConfig = new MdSnackBarConfig();
//this.snackBarConfig.horizontalPosition = this.horizontalPosition; only in current version Demo uses very old version . need to upgrade later
//this.snackBarConfig.verticalPosition = this.verticalPosition; only in current version Demo uses very old version . need to upgrade later
this.snackBarConfig.duration = parseInt(this.snackBarAutoHide, 0);
this.sb.open(message, "", this.snackBarConfig);
如下图消费服务
this.notify.openSnackBar(message);
【讨论】:
以上是关于如何在服务上使用 SnackBar 以在 Angular 2 中的每个组件中使用的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 如何在“Future”中显示“snackbar”