65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 AngularJS Interceptors 向最终用户显示通知

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2015 年 12 月 27 日

CPOL

2分钟阅读

viewsIcon

18146

描述了一种使用 AngularJS 的 Interceptors 和 HTTP 方法向最终用户显示通知的通用方法。

引言

本文描述了一种通用的方法,使用 AngularJS 的拦截器和 HTTP 方法,根据用户的操作向最终用户显示通知。例如,如果用户正在发布记录,将显示“正在保存…”的通知。如果用户正在删除记录,将显示“正在删除…”的通知,依此类推。代码使用 AngularJS 和 Typescript。

背景

我有一个需求,需要在用户执行的每个操作上都显示通知,这样即使在与数据库通信时出现延迟等情况,用户也能知道正在发生一些事情。

例如,当用户尝试查看与联系人相关的所有关联记录时,将显示“正在加载…”通知

一种方法是将通知服务注入到所有 AngularJS 服务中,然后根据操作显示通知,并在 promise 返回后隐藏通知。如果只有一页和几个操作,这很好;但是,如果需要在许多页面中重复此操作,这将违反 DRY 原则。

因此,更好的解决方案是使用 AngularJS 的拦截器 来拦截 Request / Response 并注入通知服务以显示通知。AngularJS 拦截器将使我们能够在执行请求之前和返回响应后注入自定义代码,并将其显示给最终用户。

请参阅下面的代码示例。我将在另一篇文章中展示通知服务的实际实现。

Using the Code

代码非常易于理解,但是重要的行是

  • 使用 AngularJS 注册自定义 HTTP 拦截器
    angular.module("CRM").config(['$httpProvider', ($httpProvider: any) => {
      $httpProvider.interceptors.push(HttpInterceptor.Factory); // Inject our custom interceptor
            }]);
  • 在自定义拦截器中注入自定义通知服务
        static $inject = ['$injector', '$q'];
        constructor($injector: ng.auto.IInjectorService, $q) {
            this.$q = $q;
            this.notificationService = $injector.get("CRM.Common.NotificationService");
            this.$log = $injector.get('$log');
            this.$injector = $injector;
        }
  • 使用自定义通知服务并解析 HTTP 方法
        public request = (config) => {
            this.notificationService.blockUi(this.getMessageBasedOnHttpMethod(config.method));
            return config;
        };

完整的代码如下所示

module CRM.Config {

    ((): void => {

        angular.module('CRM', [
            'toaster',
            'ngTasty',
            'ui.bootstrap',
            'darthwade.dwLoading']);

        angular.module("CRM").config(['$httpProvider', ($httpProvider: any) => {
            $httpProvider.defaults.headers.common['X-Requested-With'] = 
                      'XMLHttpRequest'; // Make angular messages MVC Ajax compatible.
            $httpProvider.interceptors.push(HttpInterceptor.Factory); // Inject our custom interceptor
        }]);

    })();

    /**
     * Custom Http Interceptor
     */
    export class HttpInterceptor {
        private $q;
        public notificationService: CRM.Common.INotificationService; // Custom Notification Service
        public $log: ng.ILogService;
        public $injector: ng.auto.IInjectorService;

        /**
         * Show the error notification and unblock the UI
         */
        public responseError = (rejection) => {
            
            this.notificationService.unblockUi();
            if (rejection.data.message) {
                this.notificationService.showError(rejection.data.message);
            }
            return this.$q.reject(rejection);
        };

        /**
         * Unblock the UI as there is no error in response
         */
        public response = (response) => {
            if (this.$q.when(response)) {
                this.notificationService.unblockUi();
                return this.$q.when(response);
            }
            return response || this.$q.when(response);
        }

        /**
         * Block the UI and show notification based on the HTTP method
         */
        public request = (config) => {
            this.notificationService.blockUi(this.getMessageBasedOnHttpMethod(config.method));
            return config;
        };

        private getMessageBasedOnHttpMethod(httpMethod : string): string {

            var message = "";

            switch (httpMethod.toLowerCase()) {
                case "get":
                    message = "Loading...";
                    break;
                case "post":
                    message = "Saving...";
                    break;
                case "put":
                    message = "Updating...";
                    break;
                case "delete":
                    message = "Deleting...";
                    break;
                default:
                    message = "Please Wait...";
            }

            return message;
        }

        /**
         * If there was any error while doing the request, unblock UI and show message
         */
        public requestError = (rejection) => {
            this.$log.log("requestError", rejection);
            this.notificationService.unblockUi();
            if (rejection.data.message) { // If MVC filter related errors
                this.notificationService.showError(rejection.data.message);
            }
            return this.$q.reject(rejection);
        };

        public static Factory($injector, $q: ng.IQService) {
            HttpInterceptor.Factory.$inject = ["$injector", "$q"];
            return new HttpInterceptor($injector, $q);
        }

        static $inject = ['$injector', '$q'];
        constructor($injector: ng.auto.IInjectorService, $q) {
            this.$q = $q;
            this.notificationService = $injector.get("CRM.Common.NotificationService");
            this.$log = $injector.get('$log');
            this.$injector = $injector;
        }
    }
}

历史

  • 2015 年 12 月 27 日:初始版本
© . All rights reserved.