AngularJS ui-router:如何全局解析所有路由的典型数据?路由、全局、典型、数据

2023-09-08 08:32:22 作者:朽梦i

我有一个 AngularJS 服务,它与服务器通信并返回应用程序不同部分的翻译:

I have an AngularJS service which communicates with the server and returns translations of different sections of the application:

angular
     .module('utils')
     .service('Translations', ['$q','$http',function($q, $http) {
        translationsService = {
            get: function(section) {
                if (!promise) {
                    var q = $q.defer();
                    promise = $http
                            .get(
                                '/api/translations',
                                {
                                    section: section
                                })
                            .success(function(data,status,headers,config) {
                                q.resolve(result.data);
                            })
                            .error(function(data,status,headers,config){ 
                                q.reject(status);
                            });
                    return q.promise;
                }
            }
        };

        return translationsService;
    }]);

节的名称作为 get 函数的 section 参数传递.

The name of the section is passed as the section parameter of the get function.

我正在使用 AngularJS ui-router 模块并遵循 此处描述的设计模式

I'm using AngularJS ui-router module and following design pattern described here

所以我有以下状态配置:

So I have the following states config:

angular.module('app')
    .config(['$stateProvider', function($stateProvider) {
    $stateProvider
    .state('users', {
        url: '/users',
        resolve: {
            translations: ['Translations',
                function(Translations) {
                    return Translations.get('users');
                }
            ]            
        },
        templateUrl: '/app/users/list.html',
        controller: 'usersController',
        controllerAs: 'vm'
    })
    .state('shifts', {
        url: '/shifts',
        resolve: {
            translations: ['Translations',
                function(Translations) {
                    return Translations.get('shifts');
                }
            ]            
        },
        templateUrl: '/app/shifts/list.html',
        controller: 'shiftsController',
        controllerAs: 'vm'
    })

这很好用,但您可能注意到我必须在 resolve 参数中明确指定 translations.我认为这还不够好,因为这重复了逻辑.

This works fine but as you may notice I have to explicitly specify translations in the resolve parameter. I think that's not good enough as this duplicates the logic.

有什么方法可以全局解析翻译并避免代码重复.我的意思是某种中间件.

Is there any way to resolve translations globally and avoid the code duplicates. I mean some kind of middleware.

我正在考虑监听 $stateChangeStart,然后获取特定于新状态的翻译并将它们绑定到控制器,但我还没有找到方法.

I was thinking about listening for the $stateChangeStart, then get translations specific to the new state and bind them to controllers, but I have not found the way to do it.

任何建议将不胜感激.

重要提示:在我的情况下,解析的 translations object 必须包含翻译数据,而不是 service/factory/whatever.

Important note: In my case the resolved translations object must contain the translations data, not service/factory/whatever.

亲切的问候.

推荐答案

虽然这是一个非常古老的问题,但我想发布我现在正在使用的解决方案.希望它会在未来对某人有所帮助.在使用了一些不同的方法后,我想出了一个 John Papa 的美丽 angularjs 模式

Though this is a very old question, I'd like to post solution which I'm using now. Hope it will help somebody in the future. After using some different approaches I came up with a beautiful angularjs pattern by John Papa

他建议使用特殊服务 routerHelperProvider 并将状态配置为常规 JS 对象.我不会在这里复制粘贴整个提供程序.有关详细信息,请参阅上面的链接.但我将展示我是如何通过该服务解决我的问题的.

He suggest using a special service routerHelperProvider and configure states as a regular JS object. I'm not going to copy-paste the entire provider here. See the link above for details. But I'm going to show how I solved my problem by the means of that service.

这是该提供者的代码部分,它获取 JS 对象并将其转换为状态配置:

Here is the part of code of that provider which takes the JS object and transforms it to the states configuration:

function configureStates(states, otherwisePath) {
    states.forEach(function(state) {
        $stateProvider.state(state.state, state.config);
});

我把它改成如下:

function configureStates(states, otherwisePath) {

    states.forEach(function(state) {

        var resolveAlways = {

            translations: ['Translations', function(Translations) {

                if (state.translationCategory) {

                    return Translations.get(state.translationCategory);

                } else {

                    return {};

                }

            }],

        };  



        state.config.resolve =

            angular.extend(state.config.resolve || {}, resolveAlways || {});



        $stateProvider.state(state.state, state.config);

    }); 

}); 

我的路由配置对象现在如下所示:

And my route configuration object now looks as follows:

        {
            state: ‘users’,
            translationsCategory: ‘users’,
            config: {
                controller: ‘usersController’
                controllerAs: ‘vm’,
                url: ‘/users’.
                templateUrl: ‘users.html'
            }

所以我做了什么:

我实现了 resolveAlways 对象,该对象采用自定义 translationsCategory 属性,注入 Translations 服务并解析必要的数据.现在不需要每次都这样做了.

I implemented the resolveAlways object which takes the custom translationsCategory property, injects the Translations service and resolves the necessary data. Now no need to do it everytime.