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

时间:2015-08-03 10:24:06

标签: javascript angularjs controller promise resolve

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

代码:

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的新手,我的英语也是废话,所以我希望你能理解我的问题。

1 个答案:

答案 0 :(得分:1)

我认为将会话重新加载到app.run不是正确的地方。直接添加它以解析和签出$q的文档,以了解promises的工作方式。

因为你无法致电承诺或推迟。您需要调用一个返回承诺的函数,然后您可以在承诺解决后添加then方法来执行您的工作。

请查看下面的演示或jsfiddle

这只是一个用$timeout模拟auth的异步方法,因为我没有在演示中添加后端。

您可以将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>