ui-router:不要等待解析所有结算以显示视图

时间:2015-09-28 10:55:41

标签: angularjs promise angular-ui-router

我正在使用ui-router在给定状态下加载不同的子视图。有些观点需要花费很长时间才能解决的资源,所以我希望在他们准备好后立即显示我的其他观点。

以下是我获取资源的方式:

.config(['$stateProvider', '$routeProvider',  
    function ($stateProvider, $routeProvider) {
        $stateProvider
            .state('test', {
                abstract: true,
                url: '/test',
                views: {
                    'main': {
                         template:  '<h1>Hello!!!</h1>' +
                                    '<div ui-view="view1"></div>' +
                                    '<div ui-view="view2"></div>'
                    }
                }
            })
            .state('test.subs', {
                url: '',
                views: {
                    'view1@test': {
                        template: "Im View1: {{ item }}",
                        controller: 'View1Ctrl',
                        resolve: {
                            test1: function () { return 'yo' }
                        }
                    },
                    'view2@test': {
                        template: "Im View2: {{ item }}",
                        controller: 'View2Ctrl',
                        resolve: {
                            // This takes a lot of time to resolve
                            test2: function ($q, $timeout) { 
                                var deferred = $q.defer()
                                $timeout(function () { deferred.resolve('boom') }, 5000)
                                return deferred.promise
                            }
                        }
                    }
                }
            });
    }])

我创建了一个JSFiddle来举例说明我的问题: http://jsfiddle.net/o76uq5oe/6/

有没有办法不等待所有的承诺得到解决?

1 个答案:

答案 0 :(得分:2)

这是因为resolve promises应该被解析以便完成状态转换,这就是resolve依赖关系存在的原因。如果它们是为国家本身或其特定观点定义的,则无关紧要。来自the manual

  

如果所有承诺都成功解决,则$ stateChangeSuccess   触发事件并注入已解析的promise的值   进入任何引用它们的控制器。如果有任何承诺   拒绝了$ stateChangeError事件被触发。

如果视图属于不同的状态,则可以执行此操作。使用来自ui-router-extras sticky stateslike that可以解决此问题:

        ...
        .state('test.subs', {
            views: {
                'view1@test': {
                    template: "Im View1: {{ item }}",
                    controller: 'View1Ctrl',
                    resolve: {
                        test1: function () { return 'yo' }
                    }
                },
            },
            sticky: true,
            onEnter: function ($state) {
              $state.transition.then(function () {
                $state.go('test.subs.view2')
              });
            }            
        })
        .state('test.subs.view2', {
            views: {
                'view2@test': {
                    template: "Im View2: {{ item }}",
                    controller: 'View2Ctrl',
                    resolve: {
                        test2: function ($q, $timeout) { 
                            var deferred = $q.defer()
                            $timeout(function () { deferred.resolve('boom') }, 1000)
                            return deferred.promise
                        }
                    }
                }
            }
        });

否则应该在视图控制器中解决依赖关系,就像没有路由器和resolve一样。