Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
334 views
in Technique[技术] by (71.8m points)

javascript - Promise dependency resolution order in angular ui-router

I have set up a top-level controller that is instantiated only when a promise (returned by a Config factory) is successfully resolved. That promise basically downloads the Web app configuration, with RESTful endpoints and so on.

$stateProvider
  .state('app', {
    url: '/',
    templateUrl: 'views/_index.html',
    controller: 'MainCtrl',
    resolve: {
      config: 'Config'
    }
  });

This setup allows me to kind-of assert that the configuration is properly loaded before any lower controller gets a chance to use it.

Now I need to inject, in a deeper nested controller, another factory that uses Config and only works when it is resolved (look at it like a $resource wrapper that needs some Web service URLs). If I do:

$stateProvider
  .state('app.bottom.page', {
    url: '/bottom/page',
    templateUrl: 'views/_a_view.html',
    controller: 'BottomLevelCtrl',
    resolve: {
      TheResource: 'MyConfigDependingResource'
    }
  });

it looks like the resolve evaluation order does not follow the controller hierarchy from top to bottom, but from bottom to top, therefore:

  1. app.bottom.page is entered
  2. ui-router attempts to resolve MyConfigDependingResource, but the injection fails, because Config has never been initialized
  3. The ui-router resolution stops because of an error (without even throwing Errors, but that's another issue), and Config is never initialized by the top level controller

Why is ui-router resolving dependencies in a reverse order? How can I easily resolve my TheResource object after the top level MainCtrl has resolved Config (without relying on $inject, of course)?

UPDATE: from this plnkr's log you can see that the top level resolve is attempted only after the nested controller has started its own resolving process.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Similarly to @Kasper Lewau's answer, one may specify a dependency on resolves withing a single state. If one of your resolves depends on one or more resolve properties from the same resolve block. In my case checkS relies on two other resolves

.state('stateofstate', {
    url: "/anrapasd",
    templateUrl: "views/anrapasd.html",
    controller: 'SteofsteCtrl',
    resolve: {
        currU: function(gamMag) {
            return gamMag.checkWifi("jabadabadu")
        },
        userC: function(gamUser, $stateParams) {
            return gamUser.getBipi("oink")
        },
        checkS: ['currU', 'userC', 'gamMag', function(currU, userC, gamMag) {
            return gamMag.check(currU, userC);
        }]
    }
})

**PS: **Check the "Resolves" section of the following document for more details about the inner-workings of resolve.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...