3

我正在尝试实例化一个控制器,使用“resolve”对象传递参数。这是语法:

{
  controller: 'HtmlModalController',
  resolve: {
    myarg: function() {
      return "FOO";
    }
  }
}

这将导致我的控制器将“myarg”变量作为参数注入,值为“FOO”。

现在,这种语法还支持 Promise,它会在实例化控制器时自动解析。

  resolve: {
    myarg: function() {
      // Does the same as above (auto-resolved promise)
      return $q.when("FOO");
    }
  }

现在,问题是:如何将承诺注入控制器?我不希望承诺得到解决,因为一旦加载控制器,我就会解决它。我尝试嵌套多个承诺,但它们都在控制器中解析回“FOO”值。

  resolve: {
    myarg: function() {
      // All promises are resolved for me :'(
      return $q.when($q.when("FOO"));
    }
  }

我现在唯一的解决方案是将承诺包装到一个函数/对象中:

  resolve: {
    myarg: function() {
      // So in my controller I can do "myarg.promise.then(...)"
      return {promise: $q.when("FOO")};
    }
  }

我知道这是一个非阻塞细节,但我想知道是否有办法正确解决“作为一个承诺”的承诺。

谢谢 =)

4

2 回答 2

2

如果没有隐式递归地解包到最终值,就无法使用 Promise 解决。使用 Promise 进行解析将始终使用 Promise 的结果而不是 Promise 本身进行解析。

唯一的选择是像你一样传递一个包装器,{p: promise }而不是then方法。

于 2015-08-11T21:01:19.450 回答
0

您可以使用的一种模式是提供承诺并在内部缓存它的服务。

function MyService() {
    var promise;
    this.getSomePromise = function() {
        if(!promise) {
            promise = $q.when(...); // whatever produces your promise
        }
        return promise;
    }
}

myModule.service('myService', MyService);

然后,您可以在控制器中依赖此服务:

myModule.controller('MyController', function(myService) {
    myService.getSomePromise().then(result => ...);
});

以及使用它来阻止您的决心:

resolve: {
    /** 
      * Note: we are not actually injecting this. 
      * Only using it to block the route. The name blocker is arbitrary and could be anything.
      */
    blocker: function(myService) {
        return myService.getSomePromise();
    }
}

这允许您将任意数量的 then 处理程序连接到服务方法,同时确保只有 1 次调用底层异步操作和 1 个 Promise 实例。

于 2016-11-22T16:49:45.317 回答