【问题标题】:Where do I put my toastr service in angular?我应该把我的 toastr 服务放在哪里?
【发布时间】:2019-12-31 07:04:28
【问题描述】:

我想要一个标准的 api 响应,如下所示。

对于成功响应:

 {
    "version": "1.0",
    "statusCode": 200,
    "result": {data....}
 }

对于错误响应:

 {
    "version": "1.0",
    "statusCode": 500, (this may be 401, 404,403,...)
    "errorMessage": {message....}
 }

我的服务如下:

export class MyService {

  constructor(private http: HttpClient) { }

  getData(): Observable<any[]> {
    return this.http.get<any[]>(`http://localhost/data`).pipe(map((response: any) => {
      return response;
    }))
  }
}

如果使用 toastr 的响应有错误,我需要显示弹出窗口。那么我在哪里使用我的 toastr 服务以获得最佳解决方案?

  • 组件类
  • 服务类
  • Http 拦截器

我不想重复自己。

【问题讨论】:

  • 组件更好
  • 如果您不会显示除errorMessage 以外的任何内容(即特定于组件的内容),那么拦截器或自定义HTTP 服务可能是一个更好的地方,以免重复相同的代码。但是如果你想显示一些特定于组件的消息,那么最好注入你想要的组件。
  • @HarunYilmaz 我更新了 pust,我的错误类型代码可能是 401, 404,403, ....
  • 我认为最好为它创建一个服务。原因是我通常使用 Angular Material 的 Snackbar (material.angular.io/components/snack-bar/overview) 来完成您想做的事情。然后,我会在 HTTPWrapper 中使用该服务,或者在普通消息的拦截器中使用该服务,然后在特定消息的组件中使用它。
  • 那么我建议通过检查响应状态来捕获和处理拦截器中的错误。

标签: angular toastr


【解决方案1】:

如果你有很多 http 请求,你可以通过在 http 拦截器 中使用它来集中它,试试这样:

@Injectable()
export class HttpInterceptor implements HttpInterceptor {
constructor(public toasterService: ToastrService) {}

intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {

    return next.handle(req).pipe(
        tap(evt => {
            if (evt instanceof HttpResponse) {
                if(evt.body && evt.body.success)
                    this.toasterService.success(evt.body.success.message, evt.body.success.title, { positionClass: 'toast-bottom-center' });
            }
        }),
        catchError((err: any) => {
            if(err instanceof HttpErrorResponse) {
                try {
                    this.toasterService.error(err.error.message, err.error.title, { positionClass: 'toast-bottom-center' });
                } catch(e) {
                    this.toasterService.error('An error occurred', '', { positionClass: 'toast-bottom-center' });
                }
                //log error 
            }
            return of(err);
        }));
  }
}

【讨论】:

    【解决方案2】:

    像这样在你的组件类的constructor中调用它

    constructor(private toastr: ToastrService){}
    

    然后在任何事件中,您都可以使用它来调用它

    this.toastr.success("It works...");
    

    【讨论】:

      【解决方案3】:

      创建这样的服务:

      declare var toastr;
      
      @Injectable({
        providedIn: 'root'
      })
      export class ToastrService {
        displayToastr(type?: string, message?: string, autoFade?: boolean) {
      
          var timeOut: any = "5000"
      
          if (autoFade == false) {
            timeOut = "0"
          }
          toastr.options = {
            "closeButton": true,
            "timeOut": timeOut,
          }
      
          switch (type) {
      
            case "success":
      
              if (message == null) {
                message = "Data Saved Successfully";
              }
              toastr.success(message);
      
              break;
      
            case "error":
      
              if (message == null) {
                message = "Something Went Wrong!";
              }
              toastr.error(message);
      
              break;
      
            case "warning":
      
              if (message == null) {
                message = "Warning!";
              }
              toastr.warning(message);
      
              break;
      
            case "clear":
      
              toastr.clear();
      
              break;
      
          }
        }
      
      }
      

      然后像这样从您的组件中调用它:

      constructor(private toastr: ToastrService){}
      
      this.toastr.displayToastr("success", "User Deleted Successfully")
      

      【讨论】:

        【解决方案4】:
            import { ToastrService } from 'ngx-toastr';
            //import your service here also 
            import { MyService } from './path/to/my.service'
        
            @Component({...})
            export class YourComponent {
               constructor(private toastr: ToastrService,private myService:MyService) {}
        
               getListData() {
               var data = myService.getData();
                 if(data.statusCode==500) {
                    this.toastr.error(data.errorMessage, 'Major Error');
                 }
               }
           }
        

        【讨论】:

        • 我可以使用这种方式,但我有 http 服务请求的音调。所以你的解决方案看起来很昂贵。
        【解决方案5】:

        我建议您创建一个烤面包机服务并将该服务注入您的根拦截器中。它将帮助您生成有关 API 行为的 HTTP 错误(无论状态码是什么)。如果您想在组件级别自定义错误提示,您也可以使用它们,将服务注入到您的组件中。

        您的烤面包机服务将根据错误代码(400,403,404 等)进行切换。在您的拦截器中,只需使用状态码参数调用服务函数。

        toaster.service.ts

        httpToast(errCode){
         switch(errCode){
          case 400:
            // your statements
          break;
        
          case 404:
          // your statements
          break;
         }
          ..... // cases goes on
        }
        

        【讨论】:

          猜你喜欢
          • 2020-09-30
          • 2019-07-11
          • 1970-01-01
          • 1970-01-01
          • 2016-08-25
          • 2013-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多