javascript - AngularJS:在任何部分页面 Controller 之前调用特定函数

标签 javascript angularjs

我想在我的应用程序加载开始时调用一个特定的函数:GetSession()。此函数进行 $http 调用并从服务器获取 session token :GlobalSessionToken。然后,此 session token 用于其他 Controller 逻辑并从服务器获取数据。我在主 Controller 中调用了此 GetSession():$routeChangeStart 事件中的 MasterController 但作为异步调用,我的代码向前移动到 CustomerController$http 响应之前。

这是我的代码:

var GlobalSessionToken = '';  //will get from server later 

//Define an angular module for our app 
var myApp = angular.module('myApp', ['ngRoute']); 

//Define Routing for app 
myApp.config(['$routeProvider', function ($routeProvider) { 
    $routeProvider. 
      when('/customer', { 
          templateUrl: 'partials/customer.html', 
          controller: 'CustomerController', 
          resolve: { 
            loadData: function($q){ 
                return LoadData2($q,'home'); 
            } 
          } 
      }). 
      otherwise({ 
          redirectTo: '/home'
      }); 
}]); 

//controllers start here and are defined in their each JS file 
var controllers = {}; 

//only master controller is defined in app.js, rest are in separate js files
controllers.MasterController = function($rootScope, $http){
    $rootScope.$on('$routeChangeStart', function(){

        if(GlobalSessionToken == ''){
            GetSession();
        }

        console.log('START');
        $rootScope.loadingView = true;
    });

    $rootScope.$on('$routeChangeError', function(){
        console.log('ERROR');
        $rootScope.loadingView = false;
    });
};

controllers.CustomerController = function ($scope) { 
    if(GlobalSessionToken != ''){
        //do something
    }
} 

//adding the controllers to myApp angularjs app 
myApp.controller(controllers); 
//controllers end here 


function GetSession(){
    $http({
        url: GetSessionTokenWebMethod,
        method: "POST",
        data: "{}",
        headers: { 'Content-Type': 'application/json' }
    }).success(function (data, status, headers, config) {
        GlobalSessionToken = data;
    }).error(function (data, status, headers, config) {
        console.log(data);
    });
}

我的 HTML 包含以下部分:

<body ng-app="myApp" ng-controller="MasterController">
    <!--Placeholder for views-->
    <div ng-view="">
    </div>
</body>

我如何确保此 GetSession() 始终在我的应用程序启动的最开始和任何其他 Controller 调用之前被调用,并且只调用一次。

编辑:这就是我根据 Maxim 的回答添加 run 方法的方式。在继续使用 Controller 之前,仍然需要找出一种方法来等待 $http 调用返回。

//Some initializing code before Angular invokes controllers
myApp.run(['$rootScope','$http', '$q', function($rootScope, $http, $q) {
   return GetSession($http, $q);
}]);

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

    $http({
        url: GetSessionTokenWebMethod,
        method: "POST",
        data: "{}",
        headers: { 'Content-Type': 'application/json' }
    }).success(function (data, status, headers, config) {
        GlobalSessionToken = data;
        defer.resolve('done');
    }).error(function (data, status, headers, config) {
        console.log(data);
        defer.reject();
    });

    return defer.promise;
}

最佳答案

尽管这里的一些解决方案是完全有效的,但在我看来,路由定义的 resolve 属性是可行的方法。在每个 Controller 的 session.then 中编写您的应用程序逻辑有点太多了,我们在其中一个项目中也使用了这种方法,但我做得不太好。

最有效的方法是使用resolve 延迟 Controller 的实例化,因为它是一个内置的解决方案。唯一的问题是您必须为每个路由定义添加具有相似代码的 resolve 属性,这会导致代码重复。

要解决此问题,您可以像这样在辅助函数中修改路由定义对象:

function withSession(routeConfig) {
  routeConfig.resolve = routeConfig.resolve || {};

  routeConfig.resolve.session = ['getSessionPromise', function(getSessionPromise) {
     return getSessionPromise();
  }]

  return routeConfig;
} 

然后,像这样定义你的路线:

$routeProvider.when('/example', withSession({
  templateUrl: 'views/example.html',
  controller: 'ExampleCtrl'
}));

这是我尝试过并且最喜欢的众多解决方案之一,因为它干净且干燥。

关于javascript - AngularJS:在任何部分页面 Controller 之前调用特定函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21521727/

相关文章:

angularjs - 我们可以从 Visual Studio 任务运行器资源管理器运行 npm start

javascript - 在 Javascript 上检查互联网连接

javascript - 我可以将行或单元格插入到 HTML 表格中,然后可以通过单击单元格对其进行编辑吗?

javascript - “ng build –env=prod” 命令不起作用

javascript - 使用 useEffect 从 TMDB 获取流派列表,并且 axios 卡在加载中

javascript - 如何检查 JavaScript 中的字符串中是否存在任何数字或字母?

javascript - 如何从数组中删除/过滤特定项目?

forms - angular - 在指令中的表单元素之间动态更改验证要求

javascript - 在模式对话框中设置默认值

angularjs - 使用 typeahead 和 Angularjs 像 Outlook 一样自动完成