UI-路由器:了解根子状态的解析承诺流

UI-router: understanding resolve promises flow of the root-sub states

我正在开发 angular 应用程序,使用 ui - 路由器。

我创建了根状态,这是一个抽象的状态,旨在解决异步问题。依赖项。 所以从我的角度来看,每个子状态都应该能够在自己的解析状态属性中使用这些依赖关系。 因此,如果 abstract 根状态解析异步依赖项并且子状态也解析异步依赖项,则后者应该等待根依赖项解析,然后再启动它自己的 resolve 方法。对吗?

这是代码示例,说明了我的意思:

在相应解析中使用的异步、基于承诺的方法

 public iAmInTheRootState(): IPromise<any> {
    let deferred = this._$q.defer();

    this._$timeout(() => {
        deferred.resolve();
    }, 3000);

    return <IPromise<any>> deferred.promise;
}

public iAmInTheSubState(): IPromise<any> {
    let deferred = this._$q.defer();

    this._$timeout(() => {
        deferred.resolve();
    }, 100);

    return <IPromise<any>> deferred.promise;
}

根抽象状态:

$stateProvider
    .state('app', {
        url: '/',
        abstract: true,
        templateUrl: 'layout/app-view.html',
        resolve: {
            auth: function (Auth: IAuthService) {
                'ngInject';
                return Auth.iAmInTheRootState().then(() => {
                    console.log('I am the root state, so I should be first');
                });
            }
        }
    });

作为子状态的子状态:

$stateProvider.state('app.my-calls', {
    url: '',
    controller: 'MyCallsController',
    controllerAs: '$ctrl',
    templateUrl: 'states/my-calls/my-calls.html',
    resolve: {
        secondAuth: (Auth: IAuthService) => {
            'ngInject';
            return Auth.iAmInTheSubState().then( () => {
                console.log('although I am faster I should be second because i am in the sub state');
            });
        }
    }
})

但输出与我的预期不同:

在您的示例中,'app.my-calls' 确实是在 'app' 状态之后创建的(您可以通过记录 onEnter 回调来验证这一点。)

From Ui-router wiki

Resolve

You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.

If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.

resolve回调不是用来延迟state的创建,而是用来延迟controller的创建。

要了解完整流程,您可以记录 $stateChangeStart & $stateChangeSuccess 事件。

虽然蒂姆的回答可以看作是对我的问题的直接回答,但人们可能想了解如何让子状态等待其父级的解析方法。

查看关于此主题的github issue

简而言之:子状态应该有父状态作为依赖:

母国:

$stateProvider
.state('app', {
    url: '/',
    abstract: true,
    templateUrl: 'layout/app-view.html',
    resolve: {
        ParentAuth: function (Auth: IAuthService) {
            'ngInject';
            return Auth.iAmInTheRootState().then(() => {
                console.log('I am the root state, so I should be first');
            });
        }
    }
});

子状态:

$stateProvider.state('app.my-calls', {
url: '',
controller: 'MyCallsController',
controllerAs: '$ctrl',
templateUrl: 'states/my-calls/my-calls.html',
resolve: {
    SubAuth: (ParentAuth, Auth: IAuthService) => {
        'ngInject';
        return Auth.iAmInTheSubState().then( () => {
            console.log('although I am faster I should be second because i am in the sub state');
        });
    }
 }
 })