8

私が構築した Django バックエンドからレコードをフェッチするために restangular を使用する AngularJS ベースのフロントエンドがあります。

私は次のようにクライアントリストを呼び出しています:

var app;

app = angular.module("myApp", ["restangular"]).config(function(RestangularProvider) {
  RestangularProvider.setBaseUrl("http://172.16.91.149:8000/client/v1");
  RestangularProvider.setResponseExtractor(function(response, operation) {
    return response.objects;
  });
  return RestangularProvider.setRequestSuffix("/?callback=abc123");
});

angular.module("myApp").controller("MainCtrl", function($scope, Restangular) {
  return $scope.client = Restangular.all("client").getList();
});

Chrome は、バックエンドが HTTP 200 でデータを返すことを示しています。

abc123({
    "meta": {
        "limit": 20,
        "next": "/client/v1/client/?callback=abc123&limit=20&offset=20",
        "offset": 0,
        "previous": null,
        "total_count": 2
    },
    "objects": [{
        "id": 1,
        "name": "Test",
        "resource_uri": "/client/v1/client/1/"
    }, {
        "id": 2,
        "name": "Test 2",
        "resource_uri": "/client/v1/client/2/"
    }]
})

しかし、それが発生すると、Chrome のコンソールに次のスタック トレースが表示されます。

TypeError: Cannot set property 'route' of undefined
    at restangularizeBase (http://172.16.91.149:9000/components/restangular/src/restangular.js:395:56)
    at restangularizeCollection (http://172.16.91.149:9000/components/restangular/src/restangular.js:499:35)
    at http://172.16.91.149:9000/components/restangular/src/restangular.js:556:44
    at wrappedCallback (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6846:59)
    at http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6883:26
    at Object.Scope.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8057:28)
    at Object.Scope.$digest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:7922:25)
    at Object.Scope.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8143:24)
    at done (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9170:20)
    at completeRequest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9333:7) angular.js:5754

restangular.js の 395 行目にブレークポイントを設定しました。

L394    function restangularizeBase(parent, elem, route) {
L395        elem[config.restangularFields.route] = route;

初めてブレークポイントにヒットしたときelemは単なるオブジェクトでrouteあり、値はclient.

2 回目にブレークポイントにヒットしたときelemは未定義でroute、値はclientです。

elem2回目に未定義になる理由はありますか?

4

2 に答える 2

19

リストを要求するとき、Restangular はサーバーからのデータが単純な配列であることを期待します。ただし、結果のデータがページネーション情報などの結果のメタデータでラップされている場合、データはバラバラになります。

Django REST Framework を使用している場合は、次のようにラップされた結果が返されます。

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "name": "Foo"
        },
        {
            "id": 2,
            "name": "Bar"
        }
    ]
}

これを変換するには、応答抽出関数を作成する必要があります。モジュール設定で指定するのが最も簡単です:

angular.module('myApp', ['myApp.controllers', 'restangular']).
config(function(RestangularProvider) {
    RestangularProvider.setBaseUrl("/api");

    // This function is used to map the JSON data to something Restangular
    // expects
    RestangularProvider.setResponseExtractor(function(response, operation, what, url) {
        if (operation === "getList") {
            // Use results as the return type, and save the result metadata
            // in _resultmeta
            var newResponse = response.results;
            newResponse._resultmeta = {
                "count": response.count,
                "next": response.next,
                "previous": response.previous
            };
            return newResponse;
        }

        return response;
    });
});

これにより、メタデータを含む _resultmeta の追加プロパティを使用して、結果が単純な配列になるように再配置されます。Restangular はそれを配列で行い、それはオブジェクトであり、期待どおりに配列を処理するときに _resultmeta プロパティにアクセスできます。

于 2013-06-30T01:54:28.890 に答える