Ho poche risorse scritte su AngularJS che accedono a un'API Tastypie. Tutto funziona bene, tranne che per un dettaglio: tastypie incapsulare sempre il risultato reale all'interno di un attributo objects
su un JSON, ad esempio:AngularJS e JSON complesso restituito da django tasteypie
/api/v1/reminder/
:
{
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"
}
}
Era wasy per fissare utilizzando un callback per la chiamata get()
:
Reminder.get().$then(function (result) {
$scope.reminders = result.data.objects;
});
Ma so result.resource
è un vero e proprio Reminder
esempio.
.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;
}])
Ora ho bisogno di implementare un comportamento su mia classe Reminder
, e ho bisogno ogni elemento sul mio meta.objects
ad essere un'istanza di 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'
});
Quindi, come ottengo angularjs a capire che ogni oggetto su objects
è il risultato effettivo quindi si comporta come un elenco di istanze?
La soluzione è la creazione di un nuovo elenco iterazione sui risultati che creano le istanze, ma non è ottimale ...
Suggerimenti?
Solution di @rtcherry:
Come suggerito da rtcherry, ho usato restangular
Configurazione della lettura della richiesta dei dati:
.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;
});
}])
Caricamento dei promemoria:
function RemindersCtrl ($scope, $rootScope, Reminder) {
$scope.reminders = Reminder.getList();
}
Aggiungere il mio metodo personalizzato a Reminder
(n ot pulito come ngResource, ma fattibile):
.factory('Reminder', ['Restangular', '$filter', function(Restangular, $filter){
var Reminder = Restangular.all('reminder');
var remainingDays = function() {
//do stuff
};
// adding custom behavior
Restangular.addElementTransformer('reminder', false, function (reminder) {
reminder.remainingDays = remainingDays;
return reminder;
});
return Reminder;
}])
Solution di @moderndegree:
ho usato puro 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;
}])
mio regolatore:
Transaction.query(filter).$then(function (result) {
$scope.days = [];
var transactions = result.resource;
resource[0].remainingDays(); // it works
});
Si consiglia di provare qualcosa come [restangular] (https://github.com/mgonto/restangular). – rtcherry
whoa, sembra buono .. lo esaminerò –
fatto. non è facile come aggiungere un metodo a una risorsa angolare, ma può essere fatto ... ma restangular ripaga su molte funzioni utili. vuoi fare una risposta dal tuo commento in modo che io possa contrassegnarlo? –