我的AngularJS .run下面有以下代码,它在我的本地开发机器上完美运行但在上传到我的客户端服务器时无法工作...经过几次测试后很明显,当控制器加载时事件尚未触发,因此控制器中的大多数功能取决于此事件不起作用。有人可以告诉我我在这里做错了什么以及如何解决它?感谢
myApp.run(['AuthDataSvc', '$rootScope', function (AuthDataSvc, $rootScope) {
AuthDataSvc.getAuth().then(function(Token){
$rootScope.$broadcast('Token', Token);
}, function(status){
console.log(status);
});
}]);
答案 0 :(得分:8)
你总是会有竞争条件。我有几个选择你可以做:
1)使用服务。我并不是这个选项的粉丝,因为它会导致Spaghetti代码。大多数时候你不希望控制器在你登录之前运行。我更喜欢选项2。
myApp.run(['AuthDataSvc', '$rootScope', function (AuthDataSvc, $rootScope) {
AuthDataSvc.getAuth(); /* no op we will use the service to determine logged in */
}]);
/* inside a controller */
if(AuthDataSvc.isLoggedIn()){
//do something.
}
2)使用route.resolve。 Resolve是在路由上定义的,只有在promise被设置为已解决后,Controller才会加载。我向您展示了ui-router
和ng-route
您需要选择毒药的示例。如果你不使用ui-router
,你应该考虑它。
/* app.config ... route config.. */
var waitForLogon = {
UserToken: ["AuthDataSvc", function (AuthDataSvc) {
return AuthDataSvc.logon();
}]
};
//this is for ng-route
$routeProvider
.when('/Book/:bookId', {
templateUrl: '--',
controller: 'MyCtrl',
resolve: waitForLogon
})
//this is for ui-router
$stateProvider
.state('me', {
templateUrl: '--',
controller: 'MeCtrl',
resolve: waitForLogon
})
/* controller */
angular.module('yourapp')
.controller('MyCtrl', ["UserToken", ... , function(UserToken){
//User Token will always be here when your Ctrl loads.
});
/* service code -- */
angular.module('yourapp')
.service('AuthDataSvc', ["LogonModel", "$q", function(LogonModel, $q) {
this._q = null;
var that = this;
this._doAuth = function(){
this.getAuth().then(function(Token){ that._q.resolve(Token) }, function(error){that._q.reject(error);}
};
this.logon = function () {
if(!this._q){
this._q = $q.defer();
this._doAuth();// <-current auth do here, and resolve this._q when done
}
return this._q.promise;
};
});