9

$resourceREST サービスに Angular を使用しています。get レスポンスの癖により、CRUD アプリケーションに $resource サービスを使用できません。

次のように、新しいオブジェクトの作成 (カードの場合など) が機能します。

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 アクションの応答を任意に解析でき、必要なアクションを実装することもできます。たとえば、POST (ID が使用できない場合に新しいリソースを作成する) または PUT (ID が使用できない場合に既存のリソースを更新する) を使用することを選択する前に、オブジェクトに id プロパティがあるかどうかを確認するリソースの保存メソッドが必要でした。有効なIDが利用可能です)。

これにより、 JSON CSRF 脆弱性を処理する別の方法を実装することもできます。angular.js の方法は $http に組み込まれていますが、私の会社の REST API は JSON 配列をダミー オブジェクトにラップすることでこの問題を解決しています。上記のようなカスタム リソースを使用して、ダミー オブジェクトを解析します。

于 2012-10-09T17:41:55.940 に答える