Paw*_*lai 11 javascript angularjs
我想调用一个特定的函数:GetSession()在我的应用程序加载开始时.此函数从服务器进行$http调用并获取会话令牌:GlobalSessionToken然后,此会话令牌将用于其他控制器逻辑,并从服务器获取数据.我GetSession()在主控制器中调用了它:MasterController在$routeChangeStart事件中但是作为异步调用,我的代码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);
});
}
Run Code Online (Sandbox Code Playgroud)
我的HTML有以下部分:
<body ng-app="myApp" ng-controller="MasterController">
<!--Placeholder for views-->
<div ng-view="">
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
我怎样才能确保GetSession()在应用程序启动的最开始和任何其他控制器调用之前调用它,并且只调用一次.
编辑:这是我run根据Maxim的答案添加方法的方法.$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;
}
Run Code Online (Sandbox Code Playgroud)
Rom*_*pak 12
虽然这里的一些解决方案是完全有效的resolve,但在我看来,路线定义的属性是可行的方法.session.then在每个控制器中编写你的应用程序逻辑有点太多了,我们在其中一个项目中也使用了这样的方法而且我没有那么好用.
最有效的方法是延迟控制器的实例化resolve,因为它是一个内置的解决方案.唯一的问题是你必须resolve为每个路由定义添加具有类似代码的属性,这会导致代码重复.
要解决此问题,您可以在辅助函数中修改路由定义对象,如下所示:
function withSession(routeConfig) {
routeConfig.resolve = routeConfig.resolve || {};
routeConfig.resolve.session = ['getSessionPromise', function(getSessionPromise) {
return getSessionPromise();
}]
return routeConfig;
}
Run Code Online (Sandbox Code Playgroud)
然后,在这里定义你的路线:
$routeProvider.when('/example', withSession({
templateUrl: 'views/example.html',
controller: 'ExampleCtrl'
}));
Run Code Online (Sandbox Code Playgroud)
这是我尝试过并且最喜欢的众多解决方案之一,因为它干净且干燥.
BiA*_*AiB 10
你不能推迟控制器的初始化.
您可以将控制器代码放在Session promise回调中:
myApp.factory( 'session', 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;
} );
myApp.controller( 'ctrl', function($scope,session) {
session.then( function() {
//$scope.whatever ...
} );
} );
Run Code Online (Sandbox Code Playgroud)
替代方案:如果您不想使用此类回调,则可以使您的会话请求同步,但这将是一件非常糟糕的事情.
| 归档时间: |
|
| 查看次数: |
21831 次 |
| 最近记录: |