我试图在我的任何AngularJS应用程序控制器,指令运行之前运行以下代码,但不幸的是应用程序主页面控制器在此代码执行完之前加载,所以我想知道是否有办法确保我的所有应用程序控制器,指令在此代码完成之前不会运行/加载?感谢
myApp.run(['TokenSvc',function (TokenSvc) {
TokenSvc.getToken().then(function(serverToken){
console.log('Got it...');
}, function(status){
console.log(status);
});
}]);
答案 0 :(得分:2)
最常见的是,您会在用于此问题的resolve
或ui-router ng-route
定义中看到$state
,但这可能会有问题。如果分辨率需要一段时间,则用户只会盯着空白屏幕。当然,你可以通过使用拦截器来显示加载器来缓解这个问题,但是我认为它超出了拦截器的预期效用。
我喜欢使用某些东西来管理初始化承诺,并将该东西注入顶级控制器(即Mediator or Observer pattern):
(function () {
function UserInfoLoader($q, facebookService, githubService) {
var _initPromise = null;
function initialization() {
var deferred = $q.defer(),
_initPromise = deferred.promise,
facebookLoading = facebookService.somePromiseFunc(),
githubLoading = githubService.somePromiseFunc();
$q.all([facebookLoading, githubLoading])
.then(function (results) {
// do something interesting with the results
deferred.resolve();
// set the promise back to null in case we need to call it again next time
_initPromise = null;
});
return promise;
}
this.initialize() {
// if there's already an initialization promise, return that
return _initPromise ? _initPromise : initialization();
}
}
angular.module('myApp').service('userInfoLoader', UserInfoLoader);
}());
这很棒,因为您可以让多个控制器依赖于相同的工作流逻辑,并且他们只会产生一个承诺。
(function () {
function UserProfileController($scope, userInfoLoader) {
$scope.loading = true;
function load() {
userInfoLoader.initialize().then(function () {
$scope.loading = false;
});
}
load();
}
function UserMessagesController($scope, userInfoLoader) {
// same sort of loading thing
}
angular.module('myApp')
.controller('userProfileController', UserProfileController)
.controller('userMessagesController', UserMessagesController)
;
}());
借用上面提到的Osmani先生的书,装载机服务就像一个空中交通管制员。它协调多架"飞机之间的时间表和传递信息,但它们永远不必相互交谈。
我见过的另一种方法是使用FrontController,通常添加在body
元素上,管理全局加载器,在长时间运行的异步操作期间显示它。那很简单,所以我不会全力以赴。
答案 1 :(得分:1)
在每条路线中执行以下操作:
$routeProvider.when("/your/path", {
templateUrl: "template/path",
controller: "controllerName",
resolve: {
getToken: ['TokenSvc',function (TokenSvc) {
return TokenSvc.getToken();
}]
}
});
您需要getToken方法始终返回相同的对象。像这样:
obj.token = null;
obj.getToken = function(){
if(!obj.token){
var deferred = $q.defer();
obj.token = deferred;
deferred.promise.then(function(serverToken){
console.log("Got it. The token is ",serverToken);
}, function(status){
console.log("something is wrong ", status);
});
$http.get("url/to/token")
.success(function(data){
deferred.resolve(data);
})
.error(function(data, status){
deferred.reject(status);
});
}
return obj.token.promise;
}