0

tl;dr - app.run は、API を呼び出すたびに $rootScope.variable の値をリセットします。これを回避する方法を見つける手助けが必要です。

AngularJS + ASP.NET Web API セットアップがあります。ログイン API を除くすべての API 呼び出しでトークンを送信するには、AngularJS が必要です。このコードを 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 に保存し、そのトークンを他のすべての API 呼び出しの HTTP ヘッダーで「myToken」の値として送信します。したがって、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 呼び出しを行うと、ajaxSetup を実行するために .run に移動し、$rootScope.token が未定義として検出されます。

これを修正するにはどうすればよいですか? どうもありがとう!

4

2 に答える 2

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 に答える
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 に答える