AngularJS ui-router: how to resolve typical data globally for all routes?

喜欢而已 提交于 2019-12-02 23:13:38
Radim Köhler

Let me show you my approach. There is a working plunker

Let's have a translation.json like this:

{
  "home" : "trans for home",
  "parent" : "trans for parent",
  "parent.child" : "trans for child"
}

Now, let's introduce the super parent state root

$stateProvider
  .state('root', {
    abstract: true,
    template: '<div ui-view=""></div>',
    resolve: ['Translations'
      , function(Translations){return Translations.loadAll();}]
  });

This super root state is not having any url (not effecting any child url). Now, we will silently inject that into every state:

$stateProvider
  .state('home', {
      parent: 'root',
      url: "/home",
      templateUrl: 'tpl.html',
  })
  .state('parent', {
      parent: 'root',
      url: "/parent",
      templateUrl: 'tpl.html',
  })

As we can see, we use setting parent - and do not effect/extend the original state name.

The root state is loading the translations at one shot via new method loadAll():

.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;
}])

We do not need $q at all. Our super root state just resolves that once... via $http and loadAll() method. All these are now loaded, and we can even place that service into $rootScope:

.run(['$rootScope', '$state', '$stateParams', 'Translations',
  function ($rootScope, $state, $stateParams, Translations) {
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;
    $rootScope.Translations = Translations;
}])

And we can access it anyhwere like this:

<h5>Translation</h5>
<pre>{{Translations.get($state.current.name) | json}}</pre>

Wow... that is solution profiting almost from each feature coming with UI-Router... I'd say. All loaded once. All inherited because of $rootScope and view inheritance... all available in any child state...

Check that all here.

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

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.

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

I transformed it as follows:

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'
            }

So what I did:

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!