繁体   English   中英

在拦截器内使用`$ mdToast`触发循环依赖

[英]Using `$mdToast` inside an interceptor triggering circular dependency

题:

如何在拦截器内使用$mdToast而不触发错误?

建立:

拦截器定义:

(function () {
  'use strict';

  angular
    .module('app.components.http-errors-interceptors')
    .factory('HttpError500Interceptor', HttpError500Interceptor);

  /* @ngInject */
  function HttpError500Interceptor($q,
                                   $mdToast,
                                   $filter) {

    var interceptor           = {};
    interceptor.responseError = responseError;

    function responseError(responseError) {
      if (responseError.status === 500) {
        $mdToast.show($mdToast.simple()
                              .content($filter('translate')('APP.COMPONENTS.HTTP_ERRORS_INTERCEPTORS.500'))
                              .position('bottom right')
                              .hideDelay(5000));
      }
      return $q.reject(responseError);
    }

    return interceptor;
  }
})();

拦截器配置:

(function () {
  'use strict';

  angular
    .module('app.components.http-errors-interceptors')
    .config(moduleConfig);

  /* @ngInject */
  function moduleConfig($httpProvider) {
    $httpProvider.interceptors.push('HttpError500Interceptor');
  }
})();

问题:

当我加载应用程序时,它会触发以下错误:

未捕获错误:[$ injector:cdep]找到循环依赖项:$ http < - $ templateRequest < - $$ animateQueue < - $ animate < - $$ interimElement < - $ mdToast < - HttpError500Interceptor < - $ http < - $ templateFactory < - $ view < - $ state

过去帮助我的一个方法就是使用$injector来在运行时而不是在配置时获得依赖。 所以,像:

  /* @ngInject */
  function HttpError500Interceptor($q,
                                   $injector,
                                   $filter) {
    function responseError(responseError) {
      var $mdToast = $injector.get('$mdToast');

如果你的循环依赖不会导致问题,在这种情况下它可能不会出现问题,这将解决问题。

这两个提供的解决方案都没有为我工作,所以我在这里发布了我所做的事情,因此任何有相同问题的人都可以使用各种解决方法。

我真正想要的是拥有一个通用组件来处理名为interceptors HTTP拦截interceptors并直接从模块显示消息,并且很高兴,因为最终的解决方案更优雅,它在注入$mdToast服务时触发了这个错误。

我后来提到的解决方案,更优雅,我对此问题的第一个解决方案是:

  • 有一个通用组件来处理名为interceptors HTTP拦截interceptors
  • 有一个通用组件来处理名为notifications-hub全局通知。

然后,在interceptors模块中,我触发一个全局事件:

$rootScope.$broadcast('notifications:httpError', responseError);

然后,在notifications-hub模块中,我在事件上注册并使用$mdToast ,它在通知服务中注入时没有错误:

$rootScope.$on('notifications:httpError', function (event, responseError) { NotificationsHubService.processErrorsAndShowToast(responseError); });

NotificationsHubService是注入$mdToast的服务。

结论:

我使用全局事件作为低级拦截器和通知子系统之间的粘合剂来克服该问题。

希望它对任何人都有用。

你应该做的是创建一个在运行时为你带来烤面包机的功能

  var getToaster = ()=>{

    var toaster = $injector.get('$mdToaster');
    return toaster;
}

现在只在你需要时调用它 - 这将提供一个围绕依赖循环的工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM