AngularJS 解析后加载控制器不起作用

AngularJS load controller after resolve doesn't work

目标: 在我的应用程序中,每个控制器都应该在用户有会话/登录后初始化,因为在这个控制器中我使用登录用户的数据。

代码:

app.js

    app.run(function($q, $rootScope, AuthSvc){
    $rootScope.ajaxCall = $q.defer();
    AuthSvc.reloadSession().then(
        function(response){
            if(response!=null && response!=undefined){
                $rootScope.activeUserSession = response;
                $rootScope.ajaxCall.resolve();
            }else{
                $rootScope.activeUserSession = null;
                $rootScope.ajaxCall.reject();
            }
        });
    return $rootScope.ajaxCall.promise;
});

routes.js

.config(['$routeProvider',
    function($routeProvider) {
        $routeProvider.
            when('/timeTracking', {
                templateUrl: 'partials/timeTracking/projectView.html',
                controller: 'timeTrackingController',
                resolve: {
                    response: function($rootScope, $q) {
                        var defer = $q.defer();
                        $rootScope.ajaxCall.promise.then(
                            function(){
                                defer.resolve();
                                return defer.promise;
                            });
                    }
                }
            }).

问题:控制器有时会在用户进行会话之前初始化,我不明白为什么。

对不起,我是Angular的新手,我的英语也很烂,所以我希望你能理解我的问题。

我认为将您的会话重新加载到 app.run 是不正确的地方。直接添加它来解析并查看 $q 的文档以了解 promises 是如何工作的。

因为你不能调用 promise 或 defer。您需要调用一个返回承诺的函数,然后您可以添加 then 方法在承诺得到解决后执行您的操作。

请查看下面或此处的演示 jsfiddle

只是用$timeout来模拟auth的异步方式,因为我demo中没有后端可以添加

您可以将您的 AuthSvc 直接添加到 resolve

angular.module('demoApp', ['ngRoute'])
.controller('timeTrackingController', function($scope, response) {
    $scope.data = response;
})
.factory('authService', function($q, $timeout) {
    return {
        reloadSession: function() {
            var deferred = $q.defer();
            $timeout(function() {
                // just simulate session reload
                // real api would to the job here
                console.log('resolved defer now!!');
                deferred.resolve({dummyData: 'hello from service'});                
            }, 1000);
            
            return deferred.promise;
        }
    }
})
.config(['$routeProvider',
    function($routeProvider) {
        $routeProvider.
            when('/timeTracking', {
                templateUrl: 'partials/timeTracking/projectView.html',
                controller: 'timeTrackingController',
                resolve: {
                    response: function(authService) {
                        return authService.reloadSession().then(function(data) {
                            return data;
                        })
                    }
                }
            })
        .otherwise('/timeTracking');
    }]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular-route.js"></script>

<div ng-app="demoApp">
    <script type="text/ng-template" id="partials/timeTracking/projectView.html">
        project view: {{data | json}}
    </script>
    <div ng-view=""></div>
</div>