AngularJS 资源承诺

Posted

技术标签:

【中文标题】AngularJS 资源承诺【英文标题】:AngularJS resource promise 【发布时间】:2013-10-29 17:04:24 【问题描述】:

我有一个使用 $resource 的简单控制器:

 var Regions = $resource('mocks/regions.json');

 $scope.regions = Regions.query();

我在指令中使用这个控制器(在链接函数中)

var regions = scope.regions;

但是区域是未定义的。调用是异步的非常合乎逻辑。

我的问题是如何等待结果和区域成为包含所有数据的数组?

UPDATE : 

这里是指令的定义

app.directive('ngMap', function() 
  return 
    restrict: 'EA',
    replace: 'true',
    scope: 

    ,
    template: '<div id="map"></div>',
    controller: 'AccordMapCtrl',
    link: function(scope, element, attrs) 
      var regions = scope.regions;
      console.log(regions);

      for (var region in regions) 
    ;
  );

【问题讨论】:

我遇到了同样的问题,并在链接函数中使用了@AndreyPushkarev 的解决方案。基本上链接函数中的所有逻辑都在$promise.then(function(result)...);里面。 只是为了确保我没有误解 - 解决此问题的“回调”方法在技术上与“承诺”方法一样有效,对吗? (我更喜欢 Promise 的语法,但在我看来,回调在技术上可以完成同样的事情) 是的,您可以选择 $promise.then 或简单的回调。我猜 $promise 方法更“语义化” 【参考方案1】:

如果您希望在资源调用中获得承诺,您应该使用

Regions.query().$q.then(function() .... )

更新:在当前版本中更改了承诺语法

Regions.query().$promise.then(function() ..... )

那些投反对票的人不知道它是什么以及谁首先将此承诺添加到资源对象。我在 2012 年末使用了这个功能 - 是的 2012 年。

【讨论】:

从 1.1.15 开始提供。您可能需要考虑升级版本。 我将 1.2 RC 用于真正的应用程序。这是一个关键任务应用程序,我只是没有尝试他们最近添加的一些花哨的东西。去年在我们的应用程序中以 Angular 的形式使用了资源承诺。我们刚刚添加了一些人建议的补丁,Angular 团队标记为“Good to Merge”。没什么大不了的。如果你关心那么多,那么制作一个自定义的 $http 包装器并像资源调用一样使用它,你就会得到承诺。 我在 1.0.8 的资源上使用了诺言,只是语法不同:)【参考方案2】:

如果你想使用异步方法,你需要通过 $promise 使用回调函数,示例如下:

var Regions = $resource('mocks/regions.json');

$scope.regions = Regions.query();
$scope.regions.$promise.then(function (result) 
    $scope.regions = result;
);

【讨论】:

为什么要做两个中间作业?如果正如我所料,Regions 没有在其他地方使用,那么resource('mocks/regions.json').query().$promise.then(function (result) $scope.regions = result; ); 肯定会完成这项工作。 在调试代码时有助于进行中间分配 来自 $resource 文档: ...调用 $resource 对象方法会立即返回一个空引用...这是一个有用的技巧,因为通常将资源分配给模型,然后由看法。拥有一个空对象不会导致渲染,一旦数据从服务器到达,对象就会被数据填充,并且视图会自动重新渲染自身以显示新数据。 好的,但是没有中间分配的我的版本的行为方式不同吗?在$scope.regions = result 执行之前不会呈现任何内容。 @Roamer-1888 我同意你的观点,你的代码在功能上等同于这个简单练习中接受的答案。不过,我正在开发一个更复杂的应用程序,它将数据从多个表返回到视图。为了让我的代码更简洁并实现 DRY 原则,我将调用 $resource 对象抽象为一个可重用的工厂。我将路径的唯一部分作为参数从我的控制器传递给工厂,然后将数据返回给我的控制器。这样做需要我完成与接受的答案类似的中间作业。【参考方案3】:

你也可以这样做:

Regions.query(, function(response) 
    $scope.regions = response;
    // Do stuff that depends on $scope.regions here
);

【讨论】:

但是这是正确的回调语法,而不是承诺?【参考方案4】:
/*link*/
$q.when(scope.regions).then(function(result) 
    console.log(result);
);
var Regions = $resource('mocks/regions.json');
$scope.regions = Regions.query().$promise.then(function(response) 
    return response;
);

【讨论】:

以上是关于AngularJS 资源承诺的主要内容,如果未能解决你的问题,请参考以下文章

Angularjs 承诺拒绝链

使用 AngularJS 立即返回一个已解决的承诺

AngularJS 中的链式承诺

AngularJS 测试 - 来自服务的承诺无法解决

AngularJS 承诺处理 CoffeeScript 类

AngularJS - 与其他功能之间的“链式承诺”