0

tl;dr - app.run 每次调用 API 时都会重置 $rootScope.variable 的值 - 我需要帮助找到解决方法。

我有一个 AngularJS + ASP.NET Web API 设置。我需要 AngularJS 在除登录 API 之外的每个 API 调用中发送一个令牌,我已将此代码放在我的 app.run 中:

.run(function ($rootScope) {    
    // $rootScope.token = "" // <-- removed this initialization for now
    var sendToken = $rootScope.token == null ? "" : $rootScope.token;
    $.ajaxSetup({
        headers: {
            'myToken': sendToken;
        }
    });
}

我的登录 API 在其响应中获取令牌 - 我将该值保存在 $rootScope.token 中,然后我想将该令牌作为“myToken”的值发送到所有其他 API 调用的 HTTP 标头中。所以 loginController 应该被允许更新 $rootScope 并且 $.ajaxSetup 应该得到 $rootScope.token 的更新值。这就是我的 loginController 获取令牌值并更新 $rootScope.token 的方式:

.controller('loginController', function($apiFactory, $rootScope) {
    $apiFactory.callAPI(
        '/api/login/login', 
        {'username': 'x', 'password': 'y'}, 
        function(apiResponse) {
            $rootScope.token = apiResponse.data;
    });
})

$apiFactory.callAPI 是我在工厂中为实际 API 调用制作的标准函数。

.factory('$apiFactory', function () {
    var root = {};  
    root.callAPI = function (apiName, data, successCB) {
        $.ajax({
            url: apiName,
            type: 'POST',
            data: JSON.stringify(data),
            contentType: 'application/json; charset=utf-8',
        }).done(function (apiResponse) {
            if (apiResponse.error == false) {
                successCB(apiResponse);
            }
        });
    }        
    return root;
}

LoginController 成功更新了 $rootScope.token,但是当我进行下一次 API 调用时,它转到 .run 以运行 ajaxSetup,并发现 $rootScope.token 未定义。

我应该怎么做才能解决这个问题?非常感谢!

4

2 回答 2

0

$rootScope.$broadcast正在通过应用程序范围发送事件。该应用程序的任何子作用域都可以使用一个简单的方法捕获它:$scope.$on()。

$rootScope.$broadcast("hi");

$rootScope.$on("hi", function(){
    //do something
});

.service("hiEventService",function($rootScope) {
    this.broadcast = function() {$rootScope.$broadcast("hi")}
    this.listen = function(callback) {$rootScope.$on("hi",callback)}
})
于 2016-09-15T09:15:07.230 回答
0

我们可以在 AJAX 调用中添加\扩展默认标头。

您需要使用$http服务。

jsfiddle上的示例。

angular.module('ExampleApp', [])
  .controller('ExampleController', function(ExampleService, AuthService) {
    var vm = this;
    vm.start = function() {
      ExampleService.getData();
    };
    vm.auth = function() {
      AuthService.auth();
    }
  })
  .service('ExampleService', function($http) {
    return {
      getData: function() {
        return $http.get("/urlsource");
      }
    }
  }).service('AuthService', function($http) {
    return {
      auth: function() {
        return $http.get("/auth")
          .then(function(apiResponse) {
            //after success auth add token
            $http.defaults.headers.common['myToken'] = apiResponse.data;
          })
          .catch(function() {
            // just for example in jsfiddle, because we got 404 error for request `auth` url
            $http.defaults.headers.common['myToken'] = '12314dsfsfsd';
          });
      }
    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
<div ng-app="ExampleApp">
  <div ng-controller="ExampleController as vm">
    <pre>Steps:
  1) Press "Start Request" button and check in console header
  2) Press "Simulate auth" button. This is add default header "myToken"
  3) Press "Start Request" button and check in console header "myToken".
  </pre>
    <button ng-click="vm.start()">
      Start Request
    </button>
    <button ng-click="vm.auth()">
      Simulate auth
    </button>
  </div>
</div>

不幸的是,片段不起作用。但是jsfiddle工作正常。

于 2016-09-15T10:08:42.573 回答