Why child resolution functions are executed before resolution of the parent state promises

I am using ui-router v0.2.13. This page states that:

All permissions for one state will be allowed before moving to the next state, even if they are not inserted into this child

And further

All permissions for all entered states are triggered and allow before transition to any state (regardless of whether the permission is entered somewhere)

However, in my case, the function of resolving the child state is executed before resolving the resolution of the parent solution. How is this possible?

Here:

 $stateProvider .state('route1', { url: "/route1", templateUrl: "route1.html", resolve: { parent: ["$timeout", "$q", function ($timeout, $q) { var d = $q.defer(); $timeout(function () { d.resolve(); }, 5000); return d.promise; }] } }) .state('route1.list', { url: "/list", templateUrl: "route1.list.html", controller: function ($scope) { $scope.items = ["A", "List", "Of", "Items"]; }, resolve: { child: function () { alert("I'm shown before `parent` resolved"); } } }); 

If you go to /route1/list , a warning will be shown immediately instead of waiting 5 seconds until the promise of parent permission is resolved.

+6
source share
2 answers

All permissions will be allowed before the transition is completed. But statements do not indicate that permission functions will be called synchronously. And it is right.

According to the ui-router source code , invocables are resolved as "parallel" as possible. Only those that depend on other invocables (either from the parents or from the current state declaration) will be executed after resolving their dependencies.

Thus, the only way to make child invocable for a call after parent allowed is to specify parent as a child invocable dependency.

 .state("route1",{ //.. resolve: { parent: ["$timeout", "$q", function ($timeout, $q) { var d = $q.defer(); $timeout(function () { d.resolve(); }, 5000); return d.promise; }] } }) .state("route1.list",{ //... resolve: { child: ["parent", function(parent) { //will be called only after parent is resolved }] }) 

Excerpt from GitHub resolve.js source code comments :

Invocables are called impatiently as soon as all dependencies are available. This is true even for dependencies inherited from a call to parent $resolve .

+3
source

So, what really happens is that since you do not enter the β€œparent” into the allowed child routes, it will not wait for the parent before trying to solve the problem. If you try this:

 resolve: { child: function(parent) { alert("Child Resolved!"); } } 

then your child will be called after the parent is turned off (allowed).

I believe that a document means that it will wait for all that are allowed before making the actual transition to a state, such as loading the controller and rendering templates.

In the plunker below (which I basically borrowed from the old scotch.io example), I played with relocation relocation. If the permission of the child depends on the permission of the parent, then the parent's promise is permitted before the child. If the child is independent, then the child first resolves (even if the timeout length is set to 0).

In all cases, however, the parent and child controllers are not entered, and views are not displayed until both children and the parent are allowed.

http://plnkr.co/edit/EtU03AfgUAlWNsEH0TuU?p=preview

+2
source

All Articles