9

我将 Angular$resource用于 REST 服务。由于我的 get 响应中的怪癖,我无法将 $resource 服务用于 CRUD 应用程序。

创建一个新的对象作品(比如卡片),类似于:

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

获取也有效:

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

但是,GET 响应不是对象Card本身,而是带有它的其他消息(包装对象)

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

因此,当我保存通过资源检索到的实例时,它会发送包装对象(在响应字段中包含修改后的 Card 对象)。这可能是正确的,但我的服务器期望 Card 对象而不是包装器。有没有办法自定义 $resource 以便它发送所需的对象。从文档中,看起来只能更改 url 参数。

$resource(url[, paramDefaults][, actions]);
4

1 回答 1

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;

}]);

然后,在你的控制器函数中,像 $resource 一样注入 CreditCard 工厂。

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

这允许您以任何您想要的方式解析 REST 操作的响应,还允许您实现您想要的任何操作。例如:我想在我的资源上使用 save 方法,在选择使用 POST(在没有可用 id 时创建新资源)或 PUT(在有效身份证件可用)。

这也将允许您实现处理JSON CSRF Vulnerability的不同方式。angular.js 方式内置在 $http 中,但我公司的 REST API 通过将 JSON 数组包装在一个虚拟对象中来解决这个问题。我使用上面的自定义资源来解析虚拟对象。

于 2012-10-09T17:41:55.940 回答