ruby-on-rails – AngularJS如何转换Rails API请求

我正在将AngularJS 1.x添加到用于编辑订单的表单中(在此示例中可以更改日期,发货和地址).我有一个带有几个端点的
Ruby on Rails JSON API:

GET /addresses
[{ id: 1, line1: "...", line2: "...", zip: "..." }, ...]

GET /shippings
[{ id: 1, name: "priority" }, ...]

GET /orders/:id
{ date: "...", 
  shipping: { id: 1, name: "priority" }, 
  address: { id: 1, line1: "...", line2: "...", zip: "..." } }

PATCH /orders/:id
{ date: "...",
  shipping_id: 1,
  address_attributes: { line1: "...", line2: "...", zip: "..." } }

在我的OrdersController中,我有以下内容:

var app = angular.module('app');

app.controller('OrdersController', ['$scope', 'Order', 'Address', 'Shipping',
  function($scope, Order, Address, Shipping) {
    $scope.order = Order.get({ id: 123 });
    $scope.addresses = Address.query();
    $scope.shippings = Shipping.query();

    $scope.save = function() {
      $scope.order.$save(function() {
        // ...
      }, function(error) { alert(error); });
    };
  }
]);

我的表格非常简单:

<form ng-submit="save()">
  <input type="date" ng-model="order.date" />

  <select ng-model="order.shipping" 
    ng-options="option.name for option in shippings track by option.id">
  </select>

  <input type="text" ng-model="order.address.line1" />
  <input type="text" ng-model="order.address.line2" />
  <input type="text" ng-model="order.address.zip" />

  <input type="submit" value="Save"/>
</form>

保存功能命中我的API端点 – 但参数不正确.我需要找到一种方法来转换这些格式:

{ date: "...", shipping: { ... }, address: { ... } }
{ date: "...", shipping_id: 1, address_attributes: { ... } } 

在AngularJS中这样做的推荐方法是什么?这是应该通过拦截器完成的吗?我应该创建一个新的Order资源并以所需的表单顺序复制属性吗?

最佳答案 AngularJS $resource支持在每个操作上设置transformRequest和transformResponse(参见
https://docs.angularjs.org/api/ngResource/service/$resource).对于你的例子:

angular.module("app").factory("OrderSerializer", function() {
  return function(data) {
    var parameters = angular.copy(data);

    if (parameters.address) {
      parameters.address_attributes = parameters.address;
      delete parameters.address;
    }

    if (parameters.shipping && parameters.s.id) {
      parameters.shipping_id = parameters.shipping.id;
      delete parameters.shipping;
    }

    return parameters;
  };
});

angular.module("app").factory("Order", ["$resource", "OrderSerializer",
  function($resource, serializer) {
    return $resource("...", { id: "@id" }, {
      "save": {
        method: "...",
        transformRequest: [serializer, angular.toJson],
      },
    });
  }
]);

如果需要高级转换,可能值得研究替换ng-resource,例如restangular.

点赞