【问题标题】:Nested promises in ui-router resolveui-router 中的嵌套承诺解析
【发布时间】:2015-09-02 21:33:42
【问题描述】:

我一直在为以下问题苦苦挣扎:

我想在视图显示之前获取一些数据,(解决)。但是有些数据依赖于另一个promise的结果。

它是这样的:我从 $stateParams 获取作业 ID(索引)并在我的服务中查找数据。完成后,从这个结果(作业)中,我可以查找设置和楼层(每个都来自不同的服务),都返回一个承诺。

到目前为止我想出了什么

jobinfo: function(Jobs, Floor, JobSetting, $stateParams, $q) {

    var defer = $q.defer();

        Jobs.getByIndex($stateParams.index)
        .then(function(job) {
            console.log('got jobs');
            $q.all({floors: Floor.getByJob(job), settings: JobSetting.getByJob(job)})
            .then(function(info) {
                console.log('got info');
                defer.resolve([job, info.floors, info.settings]);
            });
        });

    return defer.promise;
}

2 次​​em>

jobinfo: function(Jobs, Floor, JobSetting, $stateParams, $q) {

    return Jobs.getByIndex($stateParams.index)
        .then(function(job) {
            console.log('got jobs');
            return $q.all({floors: Floor.getByJob(job), settings: JobSetting.getByJob(job)})
            .then(function(info) {
                console.log('got info');
                return [job, info.floors, info.settings];
            });
        });
}

似乎都失败了,我什至没有收到console.log 的回复。

PS:我把其余的代码都省略了,显然它们被包裹在一个

resolve: {
...
}

并在正确的位置定义。

有人能这么温柔地指出我正确的方向吗?


我最终得到的解决方案如下:(感谢 avcajaraville

job: function(Jobs, $stateParams) {
    return Jobs.getByIndex($stateParams.index);
},

floors: function(Floor, job) {
    return Floor.getByJob(job);
},

settings: function(JobSetting, job) {
    return JobSetting.getByJob(job);
}

【问题讨论】:

  • 你能提供一个 JSFiddle 或 Plunkr 吗?另外,如果您在控制器中添加“jobinfo”依赖项,您会得到结果吗?您还可以检查“网络”选项卡以查看是否进行了解析调用
  • 我没有进入控制器,jobinfo 被设置为依赖,但控制器永远不会被加载。看看我能不能把这个放在小提琴里
  • 这个解析是抽象状态的一部分吗?
  • 是的,我有一个抽象的 state('app'),这个是 state('app.plan')
  • 您可能需要注入类似于@avcajaraville 答案的解析,但需要数据的任何子州除外。

标签: angularjs nested angular-ui-router promise resolve


【解决方案1】:

试试这个

jobinfo: function(Jobs, Floor, JobSetting, $stateParams, $q) {

              var defer = $q.defer();

              Jobs.getByIndex($stateParams.index)
                  .then(function(job) {
                      console.log('got jobs');
                      var floors = Floor.getByJob(job);
                      var settings = JobSetting.getByJob(job);
                      $q.all([floors, settings])
                      .then(function(info) {
                          console.log('got info');
                          defer.resolve([job, info[0], info[1]]);
                      });
                  });

              return defer.promise;
          }

【讨论】:

  • $q.all 可以取数组或对象,docs.angularjs.org/api/ng/service/$q#all
  • 我试过了,我得到了同样的结果,没有日志,也没有显示视图。
  • 你得到console.log('got jobs');记录?
【解决方案2】:

我喜欢将解析器分开。

您可以通过这种方式在每个解析器上注入值:

job : function( Jobs, $stateParams, $q ) {
    var defer = $q.defer();
    Jobs.getByIndex( $stateParams.index, function( job ) {
        defer.resolve( job );
    });
    return defer.promise;
},

floor : function( Floor, job, $q ) {
    var defer = $q.defer();
    Floor.getByJob( job, function( floor ) {
        defer.resolve( floor );
    });
    return defer.promise;
},

settings : function( JobSetting, job, $q ) {
    var defer = $q.defer();
    JobSetting.getByJob( job, function( settings ) {
        defer.resolve( settings );
    });
    return defer.promise;
},

来自ui-router documentation

resolve 属性是一个地图对象。地图对象包含

的键/值对
  • key – {string}:要注入控制器的依赖项的名称。
  • 工厂 - {string|function}:

[...]

if 函数,则将其注入,并将返回值视为 依赖。如果结果是一个承诺,它会在 控制器被实例化,其值被​​注入到 控制器。

【讨论】:

  • 您的回答让我找到了正确的解决方案。虽然当我使用 .then 或 $q 解析时以某种奇怪的方式它无法工作。我将在我的问题中添加最终结果。
  • 我认为“奇怪”的行为可能与我认为您正在使用 ngResource 的事实有关。你在用吗?
  • 我正在使用 ui-router,尽管这种状态是抽象状态的一部分,我也在使用 ionic。也许其中一个给了我这种奇怪的行为。
  • 为我工作!非常感谢。
  • @racl101 我快点!未放置!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多