2016-01-26 44 views
11

應用有兩種類型的角色:'adam'和'eve'用戶可以有一個或另一個角色。角度應用授權時多個Ajax調用

角服務來獲取角色:

app.factory("AuthService",function($http, $q){ 
    var user = undefined; 
    return { 
     getRoles : function(){ 
      var deferred = $q.defer(); 
      if(user !== undefined){ 
       deferred.resolve(user.auth); 
      }else{ 
       $http.get("./rest/auth", { 
       }).then(function(result){ 
        user = result.data; 
        deferred.resolve(user.auth); 
       }); 
      } 
      return deferred.promise; 
     } 
    }; 
}); 

路由按如下規則進行:

myApp.config(['$routeProvider', function ($routeProvider) { 
    $routeProvider 
     .when("/adam", { 
      templateUrl: 'templates/adam.html', 
      controller: 'AController' 
     }) 
     .when("/eve", { 
      templateUrl: 'templates/eve.html', 
      controller: 'BController' 
     }) 
     .when("/", { 
      resolve: { 
       load : function($q, $location, AuthService){ 
        var defer = $q.defer(); 
        AuthService.getRoles().then(function(data){ 
         if(data === 'adam'){ 
          $location.path('/adam'); 
         }else{ 
          $location.path('/eve'); 
         } 
         defer.resolve(); 
        }); 
        return defer.promise; 
       } 
      } 
     }) 
     .otherwise({ redirectTo: '/' });; 
}]); 

我需要在控制器的角色,以及執行某些操作。控制器代碼:

angular.element(document).ready(function() { 
    AuthService.getRoles().then(function(data){ 
     // some operation 
    }); 
}); 

在導航到「/」,AJAX調用兩次,因爲兩者的決心和控制器功能調用AuthService.getRoles()。我如何重構代碼,以便只調用一次Ajax?

+0

嗨,我已經更新了我的代碼 – Shohel

+0

如果一個呼叫正在經歷OPTIONS方法和其他使用GET/POST方法,這個問題得到利用下面的代碼解析: $ http.defaults .headers.post [「Content-Type」] =「application/x-www-form-urlencoded」; 您可以嘗試將內容類型替換爲application/json。我不知道它發生的原因。 –

回答

4

,使他們鉤到了同樣的承諾我會改變你的工廠是這樣的:

app.factory("AuthService", function ($http, $q) { 
    var userPromise; 
    return { 
     getRoles : function() { 
      if(!userPromise){ 
       userPromise = $http.get("./rest/auth", {}).then(function(result){ 
        return result.data; 
       }); 
      } 

      return userPromise; 
     } 
    }; 
}); 

這將創建一個承諾,如果它沒有設置,來獲取數據。之後的每次通話都會創建諾言,因此它只會鉤入最初的通話而不會進行後續通話。它不適合你的原因是你的用戶只能在$ http.get後面設置,所以第二次通過它仍然認爲它是未定義的。

0

我不明白:

不能你只是做(在你的控制器):

angular.element(document).ready(function() { 
    if($route.current !== '/'){ 
     AuthService.getRoles().then(function(data){ 
     // some operation 
    } 
    }); 
}); 

這可能是不確定的,但你的想法(可能是emit->廣播 - >在將可靠地給你的路線PARAMS一種$超時可能會有幫助。($超時0不在角骯髒,它只是將它最後在隊列中)。

+0

那麼,我提到的只是一個用例。我想要的是如果另一個呼叫掛起或數據可用,阻止來自服務的多個ajax調用。 –

0

你可以嘗試

app.factory("AuthService", function ($http, $q) { 
    var user = undefined; 
    var authSvc = null; 

    return function() { 
     if (!app.isSvcInstance) { 
      authSvc = null; 
      this.getRoles = function() { 
       var deferred = $q.defer(); 
       if (user !== undefined) { 
        deferred.resolve(user.auth); 
       } else { 
        $http.get("./rest/auth", { 

        }).then(function (result) { 
         user = result.data; 
         deferred.resolve(user.auth); 
        }); 
       } 
       return deferred.promise; 
      }; 
      authSvc = this; 
      return this; 
     } 
     return authSvc; 
    }; 
}); 

控制器

angular.element(document).ready(function() { 
    app.isSvcInstance = true; 
    var auth = new AuthService(); 
    auth.getRoles().then(function (data) { 
     // some operation 
    }); 
}); 

替代

app.factory("AuthService", function ($http, $q, $cacheFactory) { 

      var cacheSvc = $cacheFactory("myCache"); 

      return { 
       getRoles: function() { 
        var cacheFac = cacheSvc.get("authCache"); 
        var deferred = $q.defer(); 
        if (!cacheFac || cacheFac.length === 0) { 
         $http.get("./rest/auth", { 

         }).then(function (result) { 
          cacheSvc.put("authCache", result.data); 
          deferred.resolve(result.data); 
         }); 
        } else { 
         deferred.resolve(cacheSvc.get("authCache")); 
        } 
        return deferred.promise; 
       } 
      }; 
     }); 
0

你可能要檢查$ q.all功能

基本上,它結合了多種承諾在一個