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

Mar*_*k L 8 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();
});
Run Code Online (Sandbox Code Playgroud)

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/"
    }]
})
Run Code Online (Sandbox Code Playgroud)

但是一旦发生这种情况,我就会看到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
Run Code Online (Sandbox Code Playgroud)

我在restangular.js的第395行做了一个断点:

L394    function restangularizeBase(parent, elem, route) {
L395        elem[config.restangularFields.route] = route;
Run Code Online (Sandbox Code Playgroud)

第一次遇到断点elem只是一个对象,route其值为client.

第二次触发断点是elem未定义的,route其值为client.

任何想法为什么elem会在第二次未定义?

小智 19

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

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

{
    "count": 2,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "name": "Foo"
        },
        {
            "id": 2,
            "name": "Bar"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

要翻译它,您需要创建响应提取器功能.在模块配置中指定最简单:

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;
    });
});
Run Code Online (Sandbox Code Playgroud)

这会将结果重新排列为一个简单的数组,其中包含_resultmeta的附加属性,其中包含元数据.Restangular将对数组及其对象执行操作,并且可以在处理数组时访问_resultmeta属性,如您所期望的那样.

  • @ mark-l我建议你把它标记为答案.谢谢. (2认同)

mgo*_*nto 8

我是Restangular的创造者.

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

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

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

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