为什么我必须使用带有$ resource的$ promise?

时间:2016-04-11 15:08:14

标签: angularjs ngresource

不可否认,我对Angular来说相对较新,但是我使用ngResource进行REST调用。

我遵循的工厂模式似乎比较常见。

但是我只能使用$ promise.then访问REST响应。据我所知,你不需要使用$ resource。

所以我有这个工厂......

var LookupsService = angular.module('LookupsService', ['ngResource']);

LookupsService.factory('Lookups', ['$resource',
  function ($resource) {
      return $resource('http://localhost:5001/api/lookups', {});
  }]);

这失败了(未定义)

alert(Lookups.get().foo);

但这很好

    Lookups.get()
        .$promise
        .then(function (lookups) {
            alert(lookups.foo);
        });

我显然在这里遗漏了一些东西。某种男生错误; - )

更新

感谢您的帮助 - 现在非常清楚。为了清晰的答案和片段,我给@fikkatra打了个嘀嗒声。但几乎所有答案都有帮助。我必须小心使用Alert进行调试!

4 个答案:

答案 0 :(得分:3)

在承诺上使用alert将无效,即它不会在承诺中显示结果。但是,angular设计为直接使用$resource服务绑定到范围。这意味着您可以将$resource结果绑定到范围对象,而angular将在应用绑定时考虑范围对象是一个promise。这就是alert(resourceResult)不起作用的原因,但是$scope.myObj = resourceResult;(然后在视图中将其绑定)将起作用。

插入的代码段可以更清楚地解释:

var app = angular.module('myapp', ['ngResource']);

app.controller('myctrl', function($scope, $resource) {
  //this won't work:
  //alert("won't work: " + $resource('https://api.github.com/users/fikkatra').get());
  //but this will work
  $resource('https://api.github.com/users/fikkatra').get().$promise.then(function(user) {
    alert("will work: " + user.login);
  });
  //directly assigning $resource result to scope will work:
  $scope.user = $resource('https://api.github.com/users/fikkatra').get();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-resource.js"></script>
<div ng-app="myapp" ng-controller="myctrl">
  {{user.login}}
</div>

答案 1 :(得分:2)

您不必,也不应该$promise$resource一起使用。 $resource服务可以像这样使用:

(function() {
  'use strict';

  angular
    .module('app')
    .factory('MyService', MyService);

  MyService.$inject = ['$resource'];

  function MyService($resource) {
    return $resource('my/url/:id', {id: "@id"}, {
      'query': { isArray: false },
      'update': { method: "put" }
    });
  }
})();

它为您提供了几种可以在代码中使用的HTTP方法,而无需您自己编写。要使用它们,您可以执行以下操作:

function getActionTypes(){
      MyService.query(
        function success(result){
          // do stuff with result
        },
        function failure(result){
          console.error(result);
        });
    }

答案 2 :(得分:1)

你实际上并没有拥有来使用$ promise,如果你愿意的话,它就可用了。

Codepen:http://codepen.io/troylelandshields/pen/bpLoxE

angular.module('app', ['ngResource'])
.service('exampleSvc', function($resource){
  return $resource('http://jsonplaceholder.typicode.com/posts/1', {});
})
.controller('exampleCtrl', function(exampleSvc, $scope){
  $scope.result = exampleSvc.get(); 

  exampleSvc.get().$promise.then(function(val){
    //Do some other logic here on the val
    $scope.promiseResult = val;
  });

});

您还可以将.get()的结果分配给范围内的变量,并在解析请求时填充结果(在上面的第一个示例中)。这适用于将数据分配给作用域上的对象,该对象最终将显示在页面上,但对于需要使用.get()的结果执行其他操作的其他情况可能无法正常工作。 / p>

答案 3 :(得分:0)

根据specification,您可以传递成功回调,如此小代码段中所述。

var User = $resource('/user/:userId', {userId:'@id'});
var user = User.get({userId:123}, function() {
  user.abc = true;
  user.$save();
});

当资源完成时,将调用成功函数回调。

或者,您可以将承诺语法与get()一起使用,但您不需要根据示例添加自己的承诺。相反,您可以简单地执行以下操作:

 Lookups.get()
        .then(function (lookups) {
            alert(lookups.foo);
        });

这是因为get()会返回一个承诺。成功评估承诺后,将调用then()