Доступ к метаинформации, переданной в ответ json-сервера
Я использую Ember-Data Rest-Adapter, а JSON, возвращаемый с моего сервера, выглядит в основном так же, как в Документация по серийным файлам Active Model
{
"meta": { "total": 10 },
"posts": [
{ "title": "Post 1", "body": "Hello!" },
{ "title": "Post 2", "body": "Goodbye!" }
]
}
Получение данных с сервера работает, но, к сожалению, я не могу понять, где я могу получить доступ к метаинформации из моего ответа JSON.
Основываясь на моих исследованиях в github ember-data, поддержка метаинформации представляется реализована с фиксацией 1787bff.
Но даже с тестовыми примерами я не смог понять, как получить доступ к метаинформации.
App.PostController = Ember.ArrayController.extend({
....
requestSearchData: function(searchParams){
posts = App.Post.find(searchParams);
this.set('content', posts);
// don't know how to access meta["total"]
// but I want to do something like this:
// this.set('totalCount', meta["total"])
}
})
Может кто-нибудь из вас пролить свет на это для меня, пожалуйста? Я знаю, что Ember api движется быстро, но я уверен, что я просто пропустил небольшую часть и что это действительно возможно.
Ответы
Ответ 1
Я нашел более чистый подход для извлечения метаинформации из ответа сервера с помощью ember-данных.
Мы должны сказать сериализатору, какая метаинформация должна ожидать (в данном случае разбивка на страницы):
App.serializer = DS.RESTSerializer.create();
App.serializer.configure({ pagination: 'pagination' });
App.CustomAdapter = DS.RESTAdapter.extend({
serializer: App.serializer
});
App.Store = DS.Store.extend({
adapter: 'App.CustomAdapter'
});
После этого каждый раз, когда сервер отправляет мета-свойство с объектом разбивки на страницы, этот объект будет добавлен в свойство store TypeMaps
для запрашиваемого модельного класса.
Например, со следующим ответом:
{
'meta': {'pagination': { 'page': 1, 'total': 10 } },
'posts':[
...
]
}
TypeMap
для App.Post-Model будет включать объект разбивки на страницы после загрузки сообщений.
Вы не можете напрямую наблюдать свойство TypeMaps в хранилище, поэтому я добавил вычисляемое свойство PostsController для доступа к метаинформации с разбивкой на запросы:
App.PostsController = Ember.ArrayController.extend({
pagination: function () {
if (this.get('model.isLoaded')) {
modelType = this.get('model.type');
this.get('store').typeMapFor(modelType).metadata.pagination
}
}.property('model.isLoaded')
});
Я действительно не думаю, что отличное решение проблемы метаинформации, но это лучшее решение, с которым я смог придумать Ember-Data. Возможно, в будущем это будет проще.
Ответ 2
Я выяснил способ доступа к метаинформации, переданной в ответе. Но, к сожалению, это действительно не поддерживается ember-данными из коробки, и я пишу метаинформацию в глобальную переменную, которую я получаю через привязки в запрашивающем контроллере.
Я закончил настройку сериализатора, который использует RESTAdapter:
App.CustomRESTSerializer = DS.RESTSerializer.extend({
extractMeta: function(loader, type, json) {
var meta;
meta = json[this.configOption(type, 'meta')];
if (!meta) { return; }
Ember.set('App.metaDataForLastRequest', meta);
this._super(loader, type, json);
}
});
App.Store = DS.Store.extend({
revision: 11,
adapter: DS.RESTAdapter.create({
bulkCommit: false,
serializer: App.CustomRESTSerializer
})
});
Я знаю, что это не особенно красиво и на самом деле думает, что это противоречит тому, что ожидаются нам данные ember-данных, но пока он работает правильно.
Я попытаюсь улучшить работу с ember-данными и отправить запрос на перенос, когда он работает, или открыть проблему в github, когда кто-либо еще заинтересован в том, чтобы это работало.
Если кто-нибудь найдет более чистое решение, пожалуйста, дайте мне знать.
Ответ 3
Я думаю, что немедленное исправление для вас - это привязать totalCount к вашей модели (recordArray), посмотрите thread.
Еще один способ - создать собственный адаптер:
DS.Adapter.create({
find: function (store, type, id) {
$.ajax({
url: type.url,
dataType: 'jsonp',
context: store,
success: function(response){
this.load(type, id, response.data);
}
});
},
findAll: function(store, type) {
$.ajax({
url: type.url,
dataType: 'jsonp',
context: store,
success: function(response){
this.loadMany(type, response.data);
}
});
}
});
Параметр ответа при успешном обратном вызове в методе findAll должен быть тем, который вам нужен:
response: {
meta: {
totalCount: 10
},
posts: [{}, {}]
}
Надеюсь, что это поможет.