簡體   English   中英

AngularJS應用程序初始化之前的$ http請求?

[英]$http request before AngularJS app initialises?

為了確定用戶的會話是否經過身份驗證,我需要在加載第一個路由之前向服務器發出$ http請求。 在加載每個路由之前,身份驗證服務會檢查用戶的狀態以及路由所需的訪問級別,如果用戶未針對該路由進行身份驗證,則會重定向到登錄頁面。 然而,當第一次加載應用程序時,它不知道用戶,因此即使他們有經過身份驗證的會話,它也將始終重定向到登錄頁面。 所以為了解決這個問題,我試圖向服務器請求用戶狀態作為應用程序初始化的一部分。 問題是顯然$ http調用是異步的,那么在請求完成之前我如何阻止應用程序運行?

我對Angular和前端開發很新,所以我的問題可能是對javascript而不是Angular的誤解。

您可以通過在routingProvider中使用resolve來實現此目的。

這允許您在啟動控制器之前等待一些承諾得到解決。

從文檔引用:

resolve - {Object。=} - 應該注入控制器的可選依賴關系映射。 如果這些依賴項中的任何一個是promise,路由器將等待它們全部被解析或者在實例化控制器之前被拒絕。 如果成功解決了所有promise,則會注入已解析的promise的值並觸發$ routeChangeSuccess事件。

簡單的例子

    app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: {
            myVar: function($q,$http){
                var deffered = $q.defer();

                    // make your http request here and resolve its promise

                     $http.get('http://example.com/foobar')
                         .then(function(result){
                             deffered.resolve(result);
                          })

                return deffered.promise;
            }
        }}).
        otherwise({redirectTo: '/'});
}]);

然后將myVar注入到包含promise數據的控制器中。

避免額外的DI參數

您還可以通過返回您要注入的服務來避免額外的DI參數:

app.config(['$routeProvider', function($routeProvider) {
        $routeProvider.
            when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: {
                myService: function($q,$http,myService){
                  var deffered = $q.defer();

                      /*  make your http request here
                      *   then, resolve the deffered's promise with your service.
                      */

                  deffered.resolve(myService),

                  return deffered.promise;
                }
            }}).
            otherwise({redirectTo: '/'});
    }]);

顯然,在執行此類操作時,您必須將請求的結果存儲在共享服務中的任何位置。


看看Angular Docs / routeProvider

我從egghead.io的那個人那里學到了很多東西

使用sessionCreator封裝所有資源並返回一個promise。 然后resolve之后到您的控制器,這樣您就可以保持它沒有特定的promise代碼。

app.factory('sessionCreator', ['$http', '$q', 'urlApi',

  function ($http, $q, urlApi) {
    var deferred = $q.defer();

    $http.get(urlApi + '/startPoint').success(function(data) {
      // Do what you have to do for initialization.
      deferred.resolve();
    });

    return deferred.promise;
  }

]);

app.factory('Product', ['$resource', 'urlApi', 'sessionCreator',

  function($resource, urlApi, sessionCreator) {
    // encapsulate all yours services with `sessionCreator`
    return sessionCreator.then(function() {
      return $resource(urlApi + '/products', {}, {
        query: {method:'GET', params:{}, isArray: true}
      });
    });
  }

]);

app.config(['$routeProvider', function ($routeProvider) {

  var access = routingConfig.accessLevels;

  $routeProvider
    .when('/product', {
      templateUrl: 'views/products.html', controller: 'ProductCtrl',
      // resolve then in router configuration so you don't have to call `then()` inside your controllers
      resolve: { Product: ['Product', function(Product) { return Product; }] }
    })
    .otherwise({ redirectTo: '/' });
}]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM