2014-12-03 75 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添加内容通常不是最好的主意。