AngularJS / Restangular路由“无法设置未定义的属性'route'”

时间:2013-06-25 08:04:02

标签: javascript angularjs

我有一个基于AngularJS的前端,使用restangular从我建立的Django后端获取记录。

我正在拨打客户列表,其中包含以下内容:

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

第二次点击断点elem未定义且route的值为client

第二次为什么elem未被定义的任何想法?

2 个答案:

答案 0 :(得分:19)

在请求列表时,Restangular期望来自服务器的数据是一个简单的数组。但是,如果结果数据包含结果元数据(例如分页信息),则会分崩离析。

如果您使用的是Django REST Framework,它将返回如下包含的结果:

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

要翻译它,您需要创建响应提取器功能。最简单的方法是在模块config中指定:

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属性,如期望的那样。

答案 1 :(得分:8)

我是Restangular的创造者。

首先为您的集合调用restangularizeBase函数,然后为每个元素调用。

从StackTrace中,元素没问题,但是一旦将集合发送到restangularizeBase,它实际上是未定义的。请问console.log response.objects?另外,请更新到最新版本。

此外,对于默认请求参数,您应该使用defaultRequestParams而不是requestSuffix。 requestSuffix只能用于结尾“/”

让我知道我是否可以帮助你更多!