Angular-ui-router: managing dependencies with resolve

时间:2021-01-28 19:37:23

I'm trying to set up routing with the angular-ui-router plugin for angular. Before anything else should happen on the page (no matter which route), the user's data needs to be loaded. Then based on the user's data (id, username, etc.) other data components necessary for the route can be loaded.

我正在尝试使用angular-ui-router插件为angular设置路由。在页面上发生任何其他事情之前(无论哪条路线),都需要加载用户的数据。然后,基于用户的数据(id,用户名等),可以加载路由所需的其他数据组件。

Is there a pattern for this scenario? I was thinking one way to solve this would be to add the user data as a resolve on every route. However, not only does this seem very redundant and inefficient, but it also doesn't work (see code below).

这种情况有一种模式吗?我在想,解决这个问题的一种方法是在每条路线上添加用户数据作为解决方案。但是,这不仅看起来非常冗余和低效,而且它也不起作用(参见下面的代码)。

Here's a code sample that doesn't work because the collectionlist resolve doesn't wait for the userpanel resolve to finish (and I understand that that's the expected behavior):

这是一个不起作用的代码示例,因为collectionlist resolve不会等待userpanel resolve完成(我理解这是预期的行为):

.state('default', {
        url: '/',
        views: {
            'userpanel' : {
                templateUrl: 'js/partials/user_panel.html',
                controller: 'userController',
                resolve: {
                    user: function(UserResourceLoader) {
                        return UserResourceLoader();
                    }
                }
            },
            'collectionlist' : {
                templateUrl: 'js/partials/collection_list.html',
                controller: 'collectionsController',
                resolve: {
                    collectionsByUser: function(CollectionsByUserLoader, User) {
                        return CollectionsByUserLoader(User.data.id);
                    }
                }
            }
        }
    })

Any suggestions for this would be very helpful.

对此的任何建议都会非常有帮助。

1 个解决方案

#1


2  

You should be able to create a parent state which all of the other states can inherit from with the dependency.

您应该能够创建一个父状态,其中所有其他状态都可以从依赖项继承。

.state('root',{
     resolve: {
         user: function(UserResourceLoader) {
             return UserResourceLoader();
         }
     }
 })
 .state('root.default', {
    url: '/',
    views: {
        'userpanel' : {
            templateUrl: 'js/partials/user_panel.html',
            controller: 'userController'
        },
        'collectionlist' : {
            templateUrl: 'js/partials/collection_list.html',
            controller: 'collectionsController',
            resolve: {
                collectionsByUser: function(CollectionsByUserLoader, User) {
                    return CollectionsByUserLoader(User.data.id);
                }
            }
        }
    }
})     

for more information on nested states see: https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views

有关嵌套状态的更多信息,请参阅:https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views

But that doesn't help with

但这没有用

The collectionlist resolve doesn't wait for the userpanel resolve to finish (and I understand that that's the expected behavior):

collectionlist resolve不会等待userpanel resolve完成(我理解这是预期的行为):

There may be a better way but you could create a promise in the UserResourceLoader which will resolve when it finishes loading then in CollectionsByUserLoader wait on the promise and use the data when the promise resolves.

可能有更好的方法,但您可以在UserResourceLoader中创建一个承诺,它将在完成加载时解析,然后在CollectionsByUserLoader中等待承诺并在promise解析时使用数据。

Edit: a better way is to use nested resolves. If you inject the resolve from the parent function into the child function. You don't have to wait on the promise from the other resolve. like so.

编辑:更好的方法是使用嵌套的解析。如果您将父函数的解析注入子函数。你不必等待另一个决心的承诺。像这样。

.state('root.default', { 
     ...
     resolve: {
          collectionsByUser: function(**user**, CollectionsByUserLoader, User) {
                        return CollectionsByUserLoader(User.data.id);
                     }
                }
 }

#1


2  

You should be able to create a parent state which all of the other states can inherit from with the dependency.

您应该能够创建一个父状态,其中所有其他状态都可以从依赖项继承。

.state('root',{
     resolve: {
         user: function(UserResourceLoader) {
             return UserResourceLoader();
         }
     }
 })
 .state('root.default', {
    url: '/',
    views: {
        'userpanel' : {
            templateUrl: 'js/partials/user_panel.html',
            controller: 'userController'
        },
        'collectionlist' : {
            templateUrl: 'js/partials/collection_list.html',
            controller: 'collectionsController',
            resolve: {
                collectionsByUser: function(CollectionsByUserLoader, User) {
                    return CollectionsByUserLoader(User.data.id);
                }
            }
        }
    }
})     

for more information on nested states see: https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views

有关嵌套状态的更多信息,请参阅:https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views

But that doesn't help with

但这没有用

The collectionlist resolve doesn't wait for the userpanel resolve to finish (and I understand that that's the expected behavior):

collectionlist resolve不会等待userpanel resolve完成(我理解这是预期的行为):

There may be a better way but you could create a promise in the UserResourceLoader which will resolve when it finishes loading then in CollectionsByUserLoader wait on the promise and use the data when the promise resolves.

可能有更好的方法,但您可以在UserResourceLoader中创建一个承诺,它将在完成加载时解析,然后在CollectionsByUserLoader中等待承诺并在promise解析时使用数据。

Edit: a better way is to use nested resolves. If you inject the resolve from the parent function into the child function. You don't have to wait on the promise from the other resolve. like so.

编辑:更好的方法是使用嵌套的解析。如果您将父函数的解析注入子函数。你不必等待另一个决心的承诺。像这样。

.state('root.default', { 
     ...
     resolve: {
          collectionsByUser: function(**user**, CollectionsByUserLoader, User) {
                        return CollectionsByUserLoader(User.data.id);
                     }
                }
 }