2016-01-26 18 views
11

Aplikacja ma dwa rodzaje ról: "adam" i "eve" Użytkownik może mieć jedną lub drugą rolę.Kilka połączeń Ajax podczas autoryzacji aplikacji kątowej

kątowa usługa dostać role:

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; 
     } 
    }; 
}); 

Routing odbywa się w następujący sposób:

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: '/' });; 
}]); 

Muszę dostać role w sterowniku, jak również do wykonywania niektórych operacji. Kod Kontroler:

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

Na przechodząc do '/', ajax nazywa się dwa razy, ponieważ zarówno funkcja resolve i kontroler wzywa AuthService.getRoles(). Jak mogę zrestrukturyzować kod tak, aby ajax był wywoływany tylko raz?

+0

Witam, mam zaktualizowany mój kod – Shohel

+0

Jeśli jedno połączenie przechodzi metody opcji i innych za pomocą metody GET/POST, problem zostanie rozwiązany za pomocą następującego kodu: $ http.defaults .headers.post ["Content-Type"] = "application/x-www-form-urlencoded"; Możesz spróbować zastąpić typ zawartości jako aplikację/json. Nie wiem, dlaczego tak się dzieje. –

Odpowiedz

4

chciałbym zmienić swoje fabryki do czegoś takiego, tak aby zaczepić w tej samej obietnicy:

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; 
     } 
    }; 
}); 

Stwarza to obietnica, jeśli nie jest ustawiona, aby uzyskać dane. Każde następne połączenie będzie miało obietnicę, która zostanie po prostu podłączona do pierwszego połączenia i nie będzie wykonywać kolejnych połączeń. Powodem, dla którego to nie działa, jest to, że twój użytkownik ustawia się dopiero po $ http.get, więc za drugim razem nadal widzi go jako niezdefiniowany.

0

nie rozumiem:

nie można po prostu zrobić (w kontrolerze):

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

To może niezdefiniowana, ale masz pomysł (może emit-> broadcast-> na dałby ci params trasy niezawodnie. A $ Timeout może pomóc. ($ Timeout 0 nie jest brudny w kątowa to właśnie odróżnia ją ostatni w kolejce).

+0

Cóż, wspomniałem, że to tylko przypadek użycia. To, czego chcę, to zapobiec wielokrotnemu wywołaniu wywołania ajax, jeśli inne połączenie oczekuje lub dane są dostępne. –

0

można spróbować

Fabryka

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; 
    }; 
}); 

Controller

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

alternatywna

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

może chcesz sprawdzić $ q.all funkcja

Zasadniczo łączy wiele obietnic w jednym

Powiązane problemy