如何使用Angular Material服务显示MatSnackBar?

时间:2018-11-04 22:18:49

标签: angular typescript angular6 angular-material-6 angular-observable

我正在使用:Angular V6.1.0,Angular Material V6.4.1

我正在尝试捕获HTTP错误,并使用MatSnackBar显示它们。我试图在我的应用程序的每个组件(有一个http请求)中展示这一点。以免做重复的代码

否则,我应该在每个组件中重复相同的代码以显示MatSnackBar并插入错误。

这是我的服务

import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
// import { HttpClient, HttpErrorResponse, HttpRequest } from '@angular/common/http';
import { Observable, throwError, of, interval, Subject } from 'rxjs';
import { map, catchError, retryWhen, flatMap } from 'rxjs/operators';
import { url, ErrorNotification } from '../globals';
import { MatSnackBar } from '@angular/material';
import { ErrorNotificationComponent } from '../error-notification/error-notification.component';


@Injectable({
  providedIn: 'root'
})
export class XhrErrorHandlerService {
  public subj_notification: Subject<string> = new Subject();

  constructor(
    public snackBar: MatSnackBar
    ) {

  }

  public handleError (error: HttpErrorResponse | any) {
    this.snackBar.open('Error message: '+error.error.error, 'action', {
      duration: 4000,
    });
    return throwError(error);
  }
}

3 个答案:

答案 0 :(得分:1)

使用以下方法创建服务:

custom-snackbar.service.ts

@Injectable()
export class CustomSnackbarService {
    constructor(
      public snackBar: MatSnackBar,
      private zone: NgZone
    ) {
       public open(message, action = 'success', duration = 4000) {
         this.zone.run(() => {
          snackBar.open(message, action, { duration });
         }
      }
    }
}

还需要在ngZone中运行:https://github.com/angular/material2/issues/9875

然后在error-service.ts中输入

public handleError (error: HttpErrorResponse | any) {
  customSnackbarService.open(error, 'error')
  return throwError(error);
}

答案 1 :(得分:0)

问题是关于默认代码,您在任何可观察到的“错误”函数中编写了什么,以发出HTTP请求并默认情况下建立通用操作,以防从API获得任何错误HTTP 4xx响应(对于我的特殊情况) ,显示带有错误的MatSnackBar)。好吧,我找到了解决方案,避免了Angular的ErrorHandle实现: https://angular.io/api/core/ErrorHandler

这是我的XhrErrorHandlerService

import { Injectable, ErrorHandler, Injector, NgZone } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { MatSnackBar } from '@angular/material';


@Injectable({
  providedIn: 'root'
})
export class XhrErrorHandlerService implements ErrorHandler{

  constructor(
    private injector: Injector,
    public snackBar: MatSnackBar,
    private readonly zone: NgZone
  ) {}

  handleError(error: Error | HttpErrorResponse){
    if (error instanceof HttpErrorResponse) {
      for (var i = 0; i < error.error.length; i++) {
        this.zone.run(() => {
          const snackBar = this.snackBar.open(error.error[i], error.status + ' OK', {
            verticalPosition: 'bottom',
            horizontalPosition: 'center',
            duration: 3000,
          });
          snackBar.onAction().subscribe(() => {
            snackBar.dismiss();
          })
        });
      }
    }
    else{
      console.error(error);
    }
  }
}

这是我的ng模块:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ErrorHandler } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HTTP_INTERCEPTORS } from '@angular/common/http';

import * as moment from 'moment';

import { AppComponent } from './app.component';

//ANIMATIONS
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

//ANGULAR MATERIAL
import { MaterialModule } from './amaterial.module';

//SERVICES
import { AuthService } from './services/auth.service';
import { XhrErrorHandlerService } from './services/xhr-error-handler.service';

//RUTAS
import { RouteRoutingModule } from './route-routing.module';

//INTERCEPTOR
import { AuthInterceptor } from './http-interceptor/auth-interceptor';


@NgModule({
  declarations: [
    AppComponent,
  ],
  entryComponents: [],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MaterialModule,
    RouteRoutingModule,
    EntryComponentModule,
    HttpClientModule,
    FormsModule, 
    ReactiveFormsModule
  ],
  providers: [
    AuthService, 
    XhrErrorHandlerService,
    { provide: ErrorHandler, useClass: XhrErrorHandlerService }
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

  

答案 2 :(得分:0)

使用粗箭头()=>代替handleError上的功能

public handleError = (error: HttpErrorResponse | any) => {
    this.snackBar.open('Error message: '+error.error.error, 'action', {
      duration: 4000,
    });
    return throwError(error);
  }