如何在服务上使用SnackBar在Angular 2中的每个组件中使用

时间:2017-03-13 10:11:00

标签: angular angular-material2 snackbar

我有一个工作的零食吧,但它只在每个组件上,我想将它添加到我的服务上,所以我只是打电话给它。这是我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);
  }
  ...
}

5 个答案:

答案 0 :(得分:14)

如果您希望SnackBar在整个应用程序中运行,您应该将其放入app.component并与服务进行通信。

notification.service.ts:

public subj_notification: Subject<string> = new Subject();

app.component.ts:

constructor(
  private notificationService: NotificationService,
) {
  this.notificationService.subj_notification.subscribe(message => {
    snackBar.open(message);
  });
}

any.component.ts:

this.notificationService.subj_notification.next('this is a notification');

答案 1 :(得分: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, null, {panelClass: ['snackbar-error']});
  }

  success(message: string) {
    return this._snackBar.open(message, null, {panelClass: ['snackbar-success']});
  }

  info(message: string) {
    return this._snackBar.open(message, null, {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');
      });
  }

}

答案 2 :(得分:3)

要在任何地方使用它,请为其创建服务。另外,您还应该使用Snackbar配置来设置持续时间并公开Snackbar:

@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')

答案 3 :(得分:2)

您可以轻松地做到这一点。请找到我在我的一个项目中使用的样本下面的例子中,它运行完美

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 = 'glam-snackbar';
    this.snackBarRef = this.snackBar.open(message, '', this.snackBarConfig);
}

}

现在,你只需要在你的组件或你想使用它,并调用openSnackBar()方法时要显示的消息在以往任何时候注入该服务。

希望这会有所帮助!

答案 4 :(得分:2)

我正在使用版本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);