AngularJS资源承诺


75

我有一个使用$ 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) {}
    };
  });

显示您创建的指令定义?
Chandermani

完成后,我添加了指令
Thomas Pons,2013年

我有同样的问题,并在链接函数中使用了@AndreyPushkarev的解决方案。基本上,链接函数中的所有逻辑都在内部 $promise.then(function(result){...});
Elliot Vargas 2014年

只是为了确保我不会误会-从技术上讲,解决问题的“回调”方法和“承诺”方法一样有效,对吗?(我更喜欢promises的语法,但在我看来,回调在技术上将完成相同的事情)
rinogo '16

是的,您可以选择$ promise.then或简单的回调。我猜$ promise方法更“语义化”
Thomas Pons

Answers:


185

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

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

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

32
为什么要进行两次中间作业?如果按照我的期望,如果Regions不在其他地方使用,那resource('mocks/regions.json').query().$promise.then(function (result) { $scope.regions = result; });一定可以完成这项工作。
Roamer-1888

18
在调试代码时进行中间分配可能会有所帮助
Josh Diehl 2014年

1
从$ resource文档中:...调用$ resource对象方法会立即返回一个空引用...这是一个有用的技巧,因为通常将资源分配给模型,然后由视图呈现。具有空对象将导致不进行渲染,一旦数据从服务器到达,该对象就会被数据填充,并且视图会自动重新渲染以显示新数据。
jarz 2015年

可以,但是没有中间分配的版本的行为是否相同?在$scope.regions = result执行之前,不会呈现任何内容。
Roamer-1888'3

@ Roamer-1888我同意您的观点,您的代码在功能上等同于此简单练习中可接受的答案。不过,我正在开发一个更复杂的应用程序,该应用程序将数据从多个表返回到视图。为了使代码更整洁并实现DRY原则,我抽象了将$ resource对象调用到可重用工厂中的方法。我将路径的唯一部分作为参数从控制器传递给工厂,然后将数据返回给控制器。这样做需要我进行类似于已接受答案的中间作业。
steveo 2015年

36

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

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

更新:在当前版本中,promise语法已更改为:

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

那些拒绝投票的人不知道那是什么,而是首先将此承诺添加到资源对象中的。我在2012年末使用了此功能-是的2012年。


从1.1.15开始可用。您可能要考虑升级版本。
马布卜

我将1.2 RC用于实际应用程序。这是一个关键任务应用程序,我只是没有尝试他们最近添加的一些奇特的东西。去年在我们的应用程序中使用了该资源承诺内容。我们刚刚添加了一些人建议的补丁,Angular团队将其标记为“ Good to Merge”。没什么大不了的。如果您非常在意,那么可以创建一个自定义的$ http包装器,并将其用作资源调用,您将获得承诺。
Mahbub

我是在1.0.8中对资源的可靠承诺,只是语法不同:)
Thomas Pons

我将发布答案;)
Thomas Pons 2013年

20

您也可以这样做:

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

9
但是,这是正确的回调语法,不是保证吗?
ericso

0
/*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;
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.