AngularJS在app.run()中运行代码

时间:2014-04-27 12:52:20

标签: angularjs

我试图在我的任何AngularJS应用程序控制器,指令运行之前运行以下代码,但不幸的是应用程序主页面控制器在此代码执行完之前加载,所以我想知道是否有办法确保我的所有应用程序控制器,指令在此代码完成之前不会运行/加载?感谢

  myApp.run(['TokenSvc',function (TokenSvc) {

        TokenSvc.getToken().then(function(serverToken){
            console.log('Got it...');
        }, function(status){
            console.log(status);
        });    
  }]);

2 个答案:

答案 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;
}