2012-10-04 31 views
9

我使用Angular $resource进行REST服务。由于我得到的回应中有怪癖,我不能使用$资源服务为CRUD应用程序。

创建一个新的目标工作(说的卡),smilar到:

var newCard = new CreditCard(); 
newCard.name = "Mike Smith"; 
newCard.$save(); 

获得同样适用:

var card = CreditCard().get({_id:1) 

但是,获得响应不是对象Card本身,而是其他消息与它(包装对象)

{ message: ".....", 
    response: Card //object 
} 

所以当我保存实例检索ved通过资源,它发送包装器对象(在响应字段中具有修改的Card对象)。 这可能是正确的,但我的服务器期望Card对象不是包装。 有没有一种方法来定制$资源,以便它发送所需的对象。从文档看来,只有url参数可以更改。

$resource(url[, paramDefaults][, actions]); 
+0

你可以发布一个完整的例子在jsfiddle,或类似的?根据我的经验,对于(简单)CRUD,没有必要创建一个像这样的新对象。如果您只是简单地访问您的资源,例如$ scope.card = Card.get({_ id:1),其中Card是您的资源服务?另外,如果你告诉表单你的模型是什么,那么实例会自动填充。 – Narretz

+0

我不认为你的问题是在Angular中。听起来就像你在服务器端的REST实现有一些问题。不应该有附加信息。你可能想首先检查一下,以确保响应的主体只是你期望的对象。 –

+0

服务器确实在发送实际对象的包装。但是,有没有办法发送回服务器(POST) – bsr

回答

17

我也遇到了$ resource模块中的标准实现问题。有一段时间我只是在我自己的$ resource文件的本地副本中进行编辑,但是我发现我仍然不满意他们实现REST资源的方式。我需要比提供更多的灵活性。

标准$resource模块只是$ http的工厂包装。如果你把$ resource模块中的代码归纳起来,你可以很容易地创建自己的自定义实现。

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

app.factory('CreditCard', ['$http', function($http) { 

    function CreditCardFactory() { 

     function parseMessage(message) { 
      if (message.response) { 
       return message.response; 
      } 
     } 

     function CreditCard(value) { 
      angular.copy(value || {}, this); 
     } 

     CreditCard.$get = function(id) { 
      var value = this instanceof CreditCard ? this : new CreditCard(); 
      $http({ 
       method: 'GET', 
       url: '/creditcards/' + id 
      }).then(function(response) { 
       var data = response.data; 
       if (data) { 
        angular.copy(parseMessage(data), value); 
       } 
      }); 
      return value; 
     }; 

     CreditCard.prototype.$get = function(id) { 
      CreditCard.$get.call(this, id); 
     }; 

     return CreditCard; 

    } 

    return CreditCardFactory; 

}]); 

然后,你的控制器功能中,注入的信用卡式工厂就像你$资源。

app.controller('CreditCardCtrl', function($scope, CreditCard) { 
    $scope.creditCard = CreditCard().get(3); 
}); 

这可以让您无论如何解析您的REST动作的响应,并且还允许您执行任何您想要的动作。例如:我想要一个保存在我的资源上的方法,它会在选择使用POST之前检查对象是否具有id属性(在没有可用id时创建新资源)或PUT(更新现有资源有效的ID可用)。

这也可以让你实现不同的方式来处理JSON CSRF Vulnerability。 angular.js方法内置到$ http中,但我公司的REST API通过将JSON数组包装在一个虚拟对象中来修复此问题。我使用像上面那样的自定义资源来解析虚拟对象。

+0

谢谢,只有对象。我也一直在想。 – bsr

+0

这是一个很好的回应布雷特,谢谢。我工作的越多,股票'$资源'越多,我发现希望在'$ http'上面写一个自定义包装器。 – quickshiftin

+0

使用这种方法你需要实现你自己的save(),delete()等方法,正确吗? – JBCP