django tastypie返回的AngularJS和复杂JSON
我很少有关于AngularJS的资源可以访问TastypieAPI。除了一个细节外,一切都正常:tastype总是将实际结果封装在JSON上的django tastypie返回的AngularJS和复杂JSON,angularjs,angularjs-resource,Angularjs,Angularjs Resource,我很少有关于AngularJS的资源可以访问TastypieAPI。除了一个细节外,一切都正常:tastype总是将实际结果封装在JSON上的objects属性中,例如: /api/v1/rementer/: { meta: { limit: 20, next: null, offset: 0, previous: null, total_count: 3 }, objects: [{
objects
属性中,例如:
/api/v1/rementer/
:
{
meta: {
limit: 20,
next: null,
offset: 0,
previous: null,
total_count: 3
},
objects: [{
category: {
color: "#999999",
id: 1,
name: "Groceries",
resource_uri: "/api/v1/category/1"
},
description: "",
due_date: "2010-10-16",
id: 1,
repeat: "weekly",
resource_uri: "/api/v1/reminder/1",
value: "-50"
}, {
category: {
color: "#999999",
id: 1,
name: "Groceries",
resource_uri: "/api/v1/category/1"
},
description: "",
due_date: "2010-10-17",
id: 2,
repeat: "weekly",
resource_uri: "/api/v1/reminder/2",
value: "-50"
}
}
使用对get()
调用的回调来修复此问题是非常困难的:
Reminder.get().$then(function (result) {
$scope.reminders = result.data.objects;
});
但我知道结果。资源
是一个实际的提醒
实例
.factory('Reminder', ['$resource', function($resource){
var Reminder = $resource('/api/v1/reminder/:id', {}, {
get: {
method: 'GET',
isArray: false
}
});
Reminder.prototype.TESTE = function () {console.log('asd');};
return Reminder;
}])
现在我需要在我的提醒
类上实现行为,我需要元对象
上的每个元素都是提醒
的实例:
Reminder.get().$then(function (result) {
$scope.reminders = result.data.objects;
result.resource.TESTE(); // -> outputs 'asd'
o = result.data.objects[0];
o.TESTE // -> undefined, obvisously
i = new Reminder(o);
i.TESTE() // -> outputs 'asd'
});
那么,如何让angularjs理解objects
上的每个对象都是实际的结果,所以它的行为就像一个实例列表
解决方法是创建一个新的列表,在创建实例的结果上迭代,但这不是最佳的
建议
@rtcherry提供的解决方案:
正如rtcherry所建议的,我使用
配置请求数据的读取:
.config(['RestangularProvider', function(RestangularProvider) {
RestangularProvider.setBaseUrl("/api/v1");
RestangularProvider.setResponseExtractor(function(response, operation, what, url) {
var newResponse;
if (operation === "getList") {
newResponse = response.objects;
newResponse.metadata = response.meta;
} else {
newResponse = response.data;
}
return newResponse;
});
}])
加载提醒:
function RemindersCtrl ($scope, $rootScope, Reminder) {
$scope.reminders = Reminder.getList();
}
将我的自定义方法添加到提醒
(不如ngResource干净,但可行):
@modendegree提供的解决方案:
我使用了纯ngResource
:
var tastypieDataTransformer = function ($http) {
return $http.defaults.transformResponse.concat([
function (data, headersGetter) {
var result = data.objects;
result.meta = data.meta;
return result;
}
])
};
...
.factory('Reminder', ['$resource', '$http', function($resource, $http){
var Reminder = $resource('/api/v1/reminder/:id', {}, {
query: {
method: 'GET',
isArray: true,
transformResponse: tastypieDataTransformer($http)
}
});
Reminder.prototype.remainingDays = function () {
// doing stuff
};
return Reminder;
}])
我的控制器:
Transaction.query(filter).$then(function (result) {
$scope.days = [];
var transactions = result.resource;
resource[0].remainingDays(); // it works
});
你可能想试试这样的东西
需要一些配置来实现这一点。例如。如果您不想使用其他库,您应该能够执行以下操作:
$resource('/api/v1/reminder/', {}, {
query: {
method: 'GET',
isArray: true,
transformResponse: $http.defaults.transformResponse.concat([
function (data, headersGetter) {
return data.objects;
}
])
}
});
这将把您的转换附加到$HttpProvider
的默认转换器
注意:如果我在这一点上有错误,请纠正我,但我相信此功能需要v1.1.2或更高版本。我最后做了以下操作,以便将
元
对象直接保留在提醒.查询()
返回的结果上(在@modendegree的答案上展开)
它允许您直接在返回的对象上获取meta
值:
var reminders = Reminder.query(...);
console.log(reminders.meta); // Returns `meta` as expected.
我认为也可以在
remention.query的回调中执行类似的操作,因为response
对象也在那里可用。您可能想尝试类似的操作。哇,看起来不错。。我会调查的。这不像向角度资源添加方法那么简单,但可以做到。。但restangular的许多有用功能都是值得的。你想从你的评论中做出一个答案,这样我可以标记它吗?嘿,我是Restanglar的创建者。如果您必须选择,您希望哪一个更好的ngResource或Restanglar用于所有用途?为什么?感谢您提供的使restanglar更好的信息:)在1.2.12中@ModernEdge的解决方案有效吗?我试图返回对象列表,并包含一个元元素来表示整个页面(以避免再次请求)。看起来,即使我与示例中的transformResponse非常相似,meta稍后在返回的对象中也不可用。+1用于发布使用AngularJS的1.1.x分支中较新的ngResource
功能的解决方案。我要试试它!我遇到了一些问题,restangular没有给我回复post请求,它在ngresource上工作。回到后者会节省我一些时间。酷。限制必须加载的库的数量总是好的。另外,我最近发布了一个答案,解决了一个类似的问题@萨满正在寻找一种在默认转换之前转换响应的方法。。。我必须将元
保存为对象
数组上的属性,以备以后使用。。现在,我将找到一种方法,在我的所有资源(但不是全球资源)上设置此选项
var Reminder = $resource('/api/v1/reminder/', {}, {
query: {
method: 'GET',
isArray: true,
transformResponse: $http.defaults.transformResponse.concat([
function (data, headersGetter) {
return data.objects;
}
]),
interceptor: {
response: function(response) {
response.resource.meta = response.data.meta;
}
}
}
});
var reminders = Reminder.query(...);
console.log(reminders.meta); // Returns `meta` as expected.