2014-12-03 108 views
0

我正在使用angular和restangular,嘗試定義我從API獲取的默認標頭。從承諾之外訪問數據

令牌var永遠不會被最終令牌定義。我明白爲什麼,或多或少。但我還沒有想出一個辦法讓這個價值超出承諾。我已經試過範圍,什麼不是。我試過在promise中調用默認的頭文件。下面的代碼片段展示了幾次隨機嘗試的組合。

angular 
    .module('app') 
    .run(function (Restangular, TokenService) { 
     var Token; 
     TokenService.get().then(function(data) { 
       console.log(data.data); //The Correct Token from API 
       Token = data.data; 
       return data.data; 
      } 
     ); 

     Restangular.setDefaultHeaders({ 
      'X-XSRF-TOKEN': Token //Token is undefined 

     }); 
    }); 

這怎麼能正確完成?

+1

角和矩形:) – 2014-12-06 01:36:11

回答

1

是的,下面的代碼將解決使用閉包變量的JavaScript問題。它會調用Restangular來設置標題值。

angular 
    .module('app') 
    .run(function (Restangular, TokenService) { 
     TokenService.get().then(function(data) { 
      Restangular.setDefaultHeaders({ 
       'X-XSRF-TOKEN': data.data 
      }); 
     } 
    ); 
}); 

但是,這種方法有什麼問題?

TokenService是一個異步服務,Angular將開始獲取令牌並繼續初始化應用程序。使用Restangular的指令或服務可能會嘗試在TokenService.get(...)完成之前執行需要標頭令牌的操作!

有三種可能的解決方案。

  • 忽略該問題。
  • 使用狀態變量來指示令牌是否已設置,並等待它被設置
  • 在啓動角度之前獲取令牌。

首先獲取令牌。在啓動angular之前,您必須使用TokenService(我不知道它是什麼)。

angular.element(document).ready(function(){ 
     // first get token 
     TokenService.get().then(function(data){ 
      // put the token somewhere 
      window.token = data.data; 
      // then start angular 
      angular.bootstrap(document,['myApp']); 
     }); 
}); 

現在您可以在角度啓動時使用令牌。

angular 
    .module('app') 
    .run(function (Restangular) { 
     Restangular.setDefaultHeaders({ 
      'X-XSRF-TOKEN': window.token 
     }); 
    ); 
}); 

什麼TokenService是,你如何角開始前得到它,你是否應該把東西放到window是不是真正的答案的點。我只是想確保你明白應用程序啓動時和令牌設置之間會有一個lag。所以最好先做。

+1

你說得對。感謝您的細節和想法。確實,請求的異步性質導致了問題,因爲角度需要立即使用該值。雖然在發佈我的問題之前我已經摔了好幾個小時,但顯然這是錯誤的做法。我放棄了令牌服務以獲得更直接的不基於promise的ajax請求。 (現在我不能說我很清楚它們的區別),但問題立即解決了,一切都很好。感謝您的幫助。 – csduarte 2014-12-04 16:20:35

+0

@csduarte我已經解決了這個問題,使用ui-route支持解析和子視圖。我爲所有其他子路由創建'/'父路由。該父母必須解決承諾才能在令牌開始之前獲取該令牌。這爲整個應用程序創建了一個基本的啓動承諾。 – cgTag 2014-12-04 17:57:59

2

在Promise中移動Token的訪問權限。接下來的承諾會在完成之後運行,這就是爲什麼令牌未定義的原因。沒有辦法改變這種行爲。

angular 
    .module('app') 
    .run(function (Restangular, TokenService) { 
     TokenService.get().then(function(data) { 
       console.log(data.data); //The Correct Token from API 
       var token = data.data; 
       Restangular.setDefaultHeaders({ 
        'X-XSRF-TOKEN': token 
       }); 
       return data.data; 
      } 
     ); 

    }); 
+0

還值得注意的是,由於'token'拼寫錯誤,這仍然不會運行。 'token!= Token' – aaronfay 2014-12-03 23:08:30

+0

正確,我也沒有在裏面設置setter。然後函數 – Enzey 2014-12-03 23:13:39

+0

Typos不是實際代碼的一部分,當我爲了清晰起見而重新輸入時才引入。我嘗試了這種方法,並且Rectangular在諾言中不再被認可。 – csduarte 2014-12-04 06:22:26

0

如果您需要的令牌呼籲setDefaultHeaders你應該能夠直接做的唯一的事情,然後調用諸如:

TokenService.get().then(function(data) { 
     Restangular.setDefaultHeaders({ 
      'X-XSRF-TOKEN': data.data 
      }); 
    }); 

如果您需要在整個做記號可用該應用程序我想你可以在你的「運行」注入「$ rootScope」打電話,然後裏面「那麼」你可以指定它喜歡:

$rootScope.Token = data.data; 

這應該使令牌可隨時隨地ÿ ou注入$​​ rootScope;請記住,向$ rootScope添加內容通常不是最好的主意。