我有一个基于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
未被定义的任何想法?
答案 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只能用于结尾“/”
让我知道我是否可以帮助你更多!