Javascript AngularJS ui路由器:如何全局解析所有路由的典型数据?

Javascript AngularJS ui路由器:如何全局解析所有路由的典型数据?,javascript,angularjs,angular-ui-router,angularjs-service,Javascript,Angularjs,Angular Ui Router,Angularjs Service,我有一个AngularJS服务,它与服务器通信并返回 应用程序不同部分的翻译: angular .module('utils') .service('Translations', ['$q','$http',function($q, $http) { translationsService = { get: function(section) { if (!promise) {

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

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
参数传递

我正在使用AngularJS ui路由器模块和下面描述的设计模式

因此,我有以下状态:

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
。我认为这还不够好,因为这重复了逻辑

是否有任何方法可以全局解析翻译并避免代码重复。我是说某种中间件

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

任何建议都将不胜感激

重要提示: 在我的例子中,解析的
翻译对象
必须包含翻译数据,而不是服务/工厂/任何内容


亲切的问候。

让我告诉你我的方法。那里

让我们做一个
translation.json
如下:

{
  "home" : "trans for home",
  "parent" : "trans for parent",
  "parent.child" : "trans for child"
}
<h5>Translation</h5>
<pre>{{Translations.get($state.current.name) | json}}</pre>
现在,让我们介绍一下超级父状态
根状态

$stateProvider
  .state('root', {
    abstract: true,
    template: '<div ui-view=""></div>',
    resolve: ['Translations'
      , function(Translations){return Translations.loadAll();}]
  });
正如我们所看到的,我们使用设置
parent
-并且不影响/扩展原始状态名称

根状态通过新方法一次加载翻译

.service('Translations', ['$http'
    ,function($http) {
    translationsService = {
      data : {},
      loadAll : function(){
        return $http
          .get("translations.json")  
          .then(function(response){
            this.data = response.data;    
            return this.data;
          })
      },
      get: function(section) {
        return data[section];
      }
    };

    return translationsService;
}])
我们根本不需要
$q
。我们的超级根状态只解决了一次。。。通过
$http
loadAll()
方法。所有这些都已加载,我们甚至可以将该服务放入
$rootScope

.run(['$rootScope', '$state', '$stateParams', 'Translations',
  function ($rootScope, $state, $stateParams, Translations) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;
    $rootScope.Translations = Translations;
}])
我们可以像这样随时访问它:

{
  "home" : "trans for home",
  "parent" : "trans for parent",
  "parent.child" : "trans for child"
}
<h5>Translation</h5>
<pre>{{Translations.get($state.current.name) | json}}</pre>
翻译
{{Translations.get($state.current.name){json}
哇。。。这是一个解决方案,它几乎可以从UI路由器提供的每个功能中获益。。。我得说。全部加载一次。由于$rootScope和视图继承而被全部继承。。。在任何子状态下都可用


检查所有问题。

虽然这是一个非常老的问题,但我想发布我现在使用的解决方案。希望将来能对别人有所帮助。 在使用了一些不同的方法之后,我想出了一个

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

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

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);

    }); 

}); 
我将其转换如下:

        {
            state: ‘users’,
            translationsCategory: ‘users’,
            config: {
                controller: ‘usersController’
                controllerAs: ‘vm’,
                url: ‘/users’.
                templateUrl: ‘users.html'
            }
我的路由配置对象现在如下所示:

        {
            state: ‘users’,
            translationsCategory: ‘users’,
            config: {
                controller: ‘usersController’
                controllerAs: ‘vm’,
                url: ‘/users’.
                templateUrl: ‘users.html'
            }
所以我所做的是:


我实现了
resolveAlways
对象,该对象接受自定义
translationsCategory
属性,注入
Translations
服务并解析必要的数据。现在不必每次都这么做。

谢谢您的回复。不幸的是,这在我的情况下不起作用,因为我正在处理非常大规模的应用程序,并且有数千个翻译。一次装上它们是不可能的。此外,我需要有一个对象,其中包含翻译,我可以通过键访问。不是我从模板调用的服务:比如{{translations.home}。我的解决方案是一个概念。您不必加载所有这些。我只是告诉你如何做不同。只需在get中调用$http。。但是检查我的解决方案……我没有时间写一个答案,但我应该提到状态定义是简单的javascript对象。您可以将它们放在一个列表中(将
名称:
声明作为每个状态的嵌套属性)并在每个状态上循环。在迭代的每个状态上,添加解析。