$ http拦截器中的Angular UI Bootstrap模式对话框挂起浏览器

时间:2014-11-04 15:38:09

标签: angularjs angularjs-directive angular-ui angular-ui-bootstrap angularjs-http

我正在尝试实现延迟授权,只有当用户触发调用需要身份验证的API时才会引入登录对话框。我正在使用bootstrap ui.bootstrap.modal(以及模态中的ui.bootstrap.alert)。问题是这些指令明确指定了以下teamplateUrl

  • template / modal / backdrop.html(modal.js here
  • template / modal / window.html(位于modal.js here
  • template / alert / alert.html(alert.js here
像这样:

.directive('modalBackdrop', ['$timeout', function ($timeout) {
  return {
    restrict: 'EA',
    replace: true,
    templateUrl: 'template/modal/backdrop.html',
    link: function (scope, element, attrs) {
      /* ... */
    }
  };
}])

每当我调用$modal.open()并且ui-bootstrap为新的模态窗口构建DOM时,angular会尝试通过$http服务解析这些URL,即使模板已经由{{{ 3}}方法或添加<script>标记。 这基本上是在我的拦截器中引起无限递归,试图在request重载中为上面的URL引入登录对话框。

这是我的拦截器的简化版本:

.config(['$provide', '$httpProvider', function($provide, $httpProvider) {
    $provide.factory('testInterceptor', ['$injector', function($injector) {
        return {
        'request': function(config) {

            var auth = $injector.get('authService');
            var modal = $injector.get('$modal');
            if (!auth.LoggedIn) {
              var loginModal = modal.open({
                  template: 'Login screen <alert type="warning">some message</alert>',
              });
              return loginModal.result;
            }
            return config;
          }
}}]);

工作演示为$templateCache.put

有人可以建议不涉及ui.bootstrap.modalui.bootstrap.alert中使用的templateUrls硬编码的方法吗?

我还在github上将其报告为here

2 个答案:

答案 0 :(得分:5)

解决此问题的一种简单方法是,不对以template/开头的任何网址的请求强制执行身份验证。像这样:

      $provide.factory('testIntercepter', ['$q', '$injector',
        function($q, $injector) {
          return {
            'request': function(config) {
              if (config.url.indexOf('template/') == 0) {
                log('ignoring ' + config.url);
                return config;
              }

              log(config.method + ' ' + config.url);
              var auth = $injector.get('authService');
              if (!auth.LoggedIn) {
                return auth.Login();
              }
              return config;
            },
          }
        }
      ]);

示例Plunker: http://plnkr.co/edit/kADmHkfHiyKW8kd7aNep?p=preview


更复杂的选项可能是检查$templateCache是否包含所请求的URL,并跳过这些情况的身份验证:

      $provide.factory('testIntercepter', ['$q', '$injector', '$templateCache',
        function($q, $injector, $templateCache) {
          return {
            'request': function(config) {
              if ($templateCache.get(config.url)) {
                log('in $templateCache ' + config.url);
                return config;
              }

              log(config.method + ' ' + config.url);
              var auth = $injector.get('authService');
              if (!auth.LoggedIn) {
                return auth.Login();
              }
              return config;
            },
          }
        }
      ]);

Plunker:http://plnkr.co/edit/RfkTmGinobxIWmg1BrMJ?p=preview

答案 1 :(得分:0)

您不必使用templateUrl。检查此代码(也处理授权)。我使用内联模态模板。这是更大的脚本的一部分,它打开模态并允许在打开的模态对话框中进行路由,这样当你想在模态对话框中执行一系列操作时,就不必关闭模态。

$modal.open({
     template: "<div data-ng-include='templateUrl'></div>",
     controller: function ($scope, $modalInstance) {

     $modalInstance.opened
         .then(function () {
             if (startRouteName != "unauthorized") {
                 var requiredAuthorizations = 
                        $scope.getRequiredPermissions(startRouteName);
                 if (requiredAuthorizations) {
                     $scope.hasAnyPermission(requiredAuthorizations)
                         .then(function (result) {
                             if (!result) {
                                 startRouteName = "unauthorized";
                             }
                             afterModalOpened($scope);
                     });
                 } else {
                     afterModalOpened($scope);
                 }
             } else {
                 afterModalOpened($scope);
             }
         });
     }
});