Angular $资源 - 我如何使用promise?

时间:2014-11-07 19:16:31

标签: javascript angularjs angular-resource angular-promise

如何使用$ resource使用promise?

这是我的服务,

     app.service("friendService",function( $resource, $q ) {

        // Return public API.
        return({
            addFriend: addFriend,
            updateFriend: updateFriend,
            getFriends: getFriends,
            removeFriend: removeFriend
        });

        function updateFriend( friend ) {

            var postData = { 
                id: friend.id,
                name: friend.name
            };

            var request = $resource("api/update.php", null,{
                update: { 
                    method:'PUT',
                    data:postData
                }
            });


            return( request.$promise.then( handleSuccess, handleError ) );
        }

我收到此错误,

  

TypeError:request。$ promise未定义

使用$ resource执行此操作的正确方法是什么?

4 个答案:

答案 0 :(得分:3)

改变
return( request.$promise.then( handleSuccess, handleError ) );

return request.update().$promise.then(handleSuccess, handleError);

那就是说,使用这样的$resource是非常低效的,而没有利用它。最好用$http替换。

答案 1 :(得分:2)

您应该将服务简化为实际上是$ resource

app.factory('friendService', [ '$resource', function($resource) {
    return $resource('/api/friends/:id', null, {
        'update' : {
            method : 'PUT'
        }
    });
} ]);

这会自动提供以下端点(实际上这是关于$ resource的很酷的事情):

{ 'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'}
};

以下是一些使用示例:

friendService.query(success, error); // GET /friends
friendService.get({ id : "exampleId" }, success, error); // GET /friends/exampleId
friendService.save({/* no params */}, friendObjectWithId, success, error); // POST /friends/idTakenFromObject
friendService.delete({ id : "exampleId" }, {}, success, error); // DELETE /friends/exampleId
friendService.update({/* no params */}, friendObjectWithId, success, error); // PUT /friends/idTakenFromObject

所以,正如documentation的这一行描述的那样,你不需要$ promise来指定回调:

  

非GET" class" actions:Resource.action([parameters],postData,[success],[error])

所以你可以简单地做这样的事情:

friendService.update({}, friendObject, successHandler, errorHandler)

答案 2 :(得分:1)

简答:

我认为你误解了$resource是什么,因为你试图像使用$http那样使用它。

$resource$http周围的“包装器”,提供面向对象的CRUD方式与RESTful api进行交互。DOCS explain it well and provide good examples

从您的网址中,我认为您实际上并未使用REST API,因此最好使用$http服务而不是使用$ resource服务。

无论如何,这是一个有效的fiddle


资源和REST API

在angular的上下文中,资源对应于REST上下文中的资源,因此,它会期望您的web服务行为类似于RESTful应用程序。为了进一步解释,让'以你的朋友'为例......(我将重新修改你的URL以更好地匹配REST API)

API定义

采用以下REST + CRUD一致性方案(对于朋友资源)

Resource            URI             Methods allowed
Friend Collection   api/friend      GET, POST
Friend              api/friend/:id  GET, PUT

这里的基本思想是每个资源都由URI (实际上是URI的定义: - >统一资源标识符)明确表示, HTTP方法(动词)是用于定义将在所述资源上执行的操作

当然,REST不仅仅是这个,我建议你阅读这个解释SO POSTthis funny article甚至Roy Fielding's dissertation(提出REST的人)这个概念比我希望的要好得多。


网址结构

这个问题容易引起热议,您可以在此SO Postan article from Roy Fielding partially addressing this too中阅读一些有趣的观点。总而言之,REST不需要干净的URL。实际上,它不需要任何语义逻辑URL结构。

REST API必须是超文本驱动的,也就是说,给定入口点(URL),API必须是自我解释的,以便客户端可以自己“发现”资源和关系,资源类型由媒体类型。这意味着,如果网址发生变化,则API不会中断!!

因此,实际上,这可能是有效的:

Home                 /
Friend Collection    /foo
Friend Resource 1    /bar
Friend Resource 2    /baz

这也是有效的:

Home                index.php
Friend Collection   index.php?q=api/friend
Friend Resource 1   index.php?q=api/friend/1
Friend Resource 2   index.php?q=api/friend/2

或者它的堂兄,使用mod_reqrite制作“干净的网址”,可以有效

Home                /
Friend Collection   /api/friend
Friend Resource 1   /api/friend/1
Friend Resource 2   /api/friend/1

甚至这可能是有效的......

Home                /index.php
Friend Collection   /friend.php
Friend Resource 1   /friend_1.php
Friend Resource 2   /friend_2.php

服务器绝不必遵循任何模式。但是,这并不意味着你不应该坚持一个结构,必须主要用于SEO目的(或人类可读性)。并且,在最后一个示例中,可能很难开发一个依赖于每个单独资源的单个脚本的理智Web服务。 (您可能不会违反REST原则,但您可能会违反一些基本的编程规则,例如DRY ......)

此外,角度资源是关于url结构的(种类)。这不是绝对的要求,但......

关于你的具体问题,是的,你需要mod_rewrite来匹配我给你的例子。但是,您不需要mod_rewrite来创建符合REST的API。


使用角度资源模块

现在我们的API方案已经设置并遵循REST + CRUD原则,我们可以充分发挥角度资源模块的潜力。

我们可以创建“朋友”的客户端表示(界面)。

//Custom actions
var actions = {
    update: {
        method: 'PUT'
    }
}

var friendUrl = "/api/friend/:id"; // should be obtained by inspecting the API iteself, usually the parent collection. 
var Friend = $resource(friendUrl, {id: '@id'}, actions);

为了得到朋友,我们会发出GET请求(并指定它的id);

Friend.get({id: 1}).$promise.then(
    function (response) {
        //console.log(response);
    }
);

DELETE和PUT请求(我们创建并称为更新)基本相同。 $ resource还支持使用对象的方法查询检索集合。您可以使用它来检索朋友的集合。

请注意,为简单起见,我使用的是硬编码网址

答案 3 :(得分:0)

请求只是设置您的端点。你需要在它上面调用一些方法,例如request.get({id: 1}).$promise;request.query({term: 'test'}).$promise;