为什么在解决父状态promise之前执行子状态解析函数

时间:2015-08-10 18:46:25

标签: javascript angularjs angular-ui-router

我正在使用baz v0.2.13。 This page声明:

  

所有在一个状态下解决的问题都将在继续进行之前得到解决   下一个州,即使他们没有注入那个孩子

还有更多

  

所有正在输入的状态的所有结果都会被触发   在转换进入任何状态之前解决(无论如何   决心被注入某处)

但是,在我的情况下,在解析父解析承诺之前执行子状态解析功能。这怎么可能?

下面:

ui-router

如果您导航到$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"); } } }); ,则会立即显示警报,而不是等待5秒,直到父解析承诺得到解决。

2 个答案:

答案 0 :(得分:3)

保证在实际执行转换之前解决所有结果。但是这些陈述并没有指出解析函数会被同步调用。这是正确的。

根据ui-router source code,invocables被解析为" parallel"尽可能。只有依赖于其他invocable(来自父项或来自当前状态声明)的那些将在它们的依赖项被解析后执行。

因此,在child解析后调用parent可调用的唯一方法是将parent指定为child可依赖的依赖项。

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

摘自GitHub resolve.js源代码评论:

  

只要所有依赖项都可用,就会急切地调用Invocable。       即使从parent调用$resolve继承的依赖项也是如此。

答案 1 :(得分:2)

所以实际发生的是,由于您没有将“父”注入已解决的子路由,因此在尝试解析子级之前不会等待父级。如果你试试这个:

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

然后在父母的超时(解决)之后调用您孩子的解决方案。

我相信doc的意思是它会在执行实际转换到状态之前等待所有解决,例如加载控制器和渲染模板。

在下面的plunker中(我主要是从一个旧的scotch.io示例中借用的)我玩的是移动依赖项。如果子进程取决于父进程,则父进程将在子进程之前解析。如果孩子不依赖,则孩子首先解析(即使超时长度设置为0)。

但是,在所有情况下,都不会输入父控制器和子控制器,并且在子解析器和父节点都解析之前不会呈现视图。

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