Допустим, у нас есть приложение Blog, в котором есть модели Blog.Post и Blog.Quote. Пусть они выводятся сервером по адресу '/records.json' и в json выглядят вот так:
{posts: [{post1}, {post2}, {post3}], quotes: [{quote1}, {quote2}, {quote3}]}
Что бы уменьшить количество запросов к серверу и тем самым увеличить скорость получения данных, нам нужно немного изменить datasource приложения.
Шаг 1. Создать запрос:
Blog.QUERY_POSTS_AND_QUOTES = SC.Query.local([Blog.Post, Blog.Quote]);
В SC.Query.local можно передавать не только один тип записи, но и массив типов.
Шаг 2. Создать хэш-таблицу с ссылками на данные и типами записей:
Это шаг нужен что бы избежать огромного количества if в функции fetch()
Blog.Datasource = SC.DataSource.extend({
urls: {
posts_and_quotes: { url: '/records.json', records: ['posts', 'quotes'] }
},
});
Так же нам нужно поправить шан запрос, установив ему атрибум id, соответствующий имени одного из элементов urls, в данном случае posts_and_quotes:
Blog.QUERY_POSTS_AND_QUOTES = SC.Query.local([Blog.Post,Blog.Quote]).set('id','posts_and_quotes');
Шаг 3. Пишем fetch():
fetch: function(store, query) {
//Получаем id запроса и берём из urls ссылку для запроса в соответствии с этим id
var id = query.get('id');
//Если id не задан, значит запрос не должен обращаться к серверу
if(!id) return NO;
var url = this.urls[id]['url'],
funcs = this.get('fetchDidComplete'),
//Если нужна особая обработка какого нибудь запроса то в fetchDidComplete
//нужно добавить функцию, имя которой совпадает с id (ещё одна хэш-таблица).
//Если имя не указано, то по завершении запроса будет вызвана default функция
func = funcs[id] || funcs['default'];
SC.Request.getUrl(url).json().notify(this, func, store, query).send();
return YES;
}
Шаг 4. Обрабатываем полученные данные:
fetchDidComplete: {
'default': function(response, store, query) {
if (SC.ok(response)) {
//В зависимости от id берём нужные записи из полученного json
var body = this.urls[query.get('id')]['records'];
//Получаем тип записи
var recordType = query.get('recordType');
//Если тип не задан, значит их несколько и они хранятся в recordsTypes
if (!recordType) {
var recordTypes = query.get('recordTypes'); //Получаем типы записей
jQuery.each(body, function(i) {
//Загружаем в store записи разных типов. Порядок выдачи записей разных типов сервером
//и порядок этих типов в запросе должны совпадать. Т.е.:
//SC.Query.local[Scm.Product, Scm.Taxon] и {products: [{product1}, {product2}], taxons: [{taxon1}, {taxon2}]}
store.loadRecords(recordTypes[i], response.get('body')[body[i]]); });
}
else {
store.loadRecords(recordType, response.get('body'));
}
store.dataSourceDidFetchQuery(query);
} else store.dataSourceDidErrorQuery(query, response);
}
}
Шаг 5. Используем новый запрос в приложении:
var data = Blog.store.find(Blog.QUERY_POSTS_AND_QUOTES);
Теперь, что бы получить отдельно posts, а отдельно quotes используем scoped queries:
var posts = data.find(SC.Query.local(Blog.Post);
var quotes = data.find(SC.Query.local(Blog.Quote);
Ну и теперь можно заполнить ArrayController'ы приложения полученными данными:
Blog.postsController.set('content', posts);
Blog.quotesController.set('content', quotes);
Полностью datasource будет выглядеть так:
Blog.Datasource = SC.DataSource.extend({
urls: {
posts_and_quotes: { url: '/records.json', records: ['posts', 'quotes'] }
},
fetch: function(store, query) {
//Получаем id запроса и берём из urls ссылку для запроса в соответствии с этим id
var id = query.get('id');
//Если id не задан, значит запрос не должен обращаться к серверу
if(!id) return NO;
var url = this.urls[id]['url'],
funcs = this.get('fetchDidComplete'),
//Если нужна особая обработка какого нибудь запроса то в fetchDidComplete
//нужно добавить функцию, имя которой совпадает с id (ещё одна хэш-таблица).
//Если имя не указано, то по завершении запроса будет вызвана default функция
func = funcs[id] || funcs['default'];
SC.Request.getUrl(url).json().notify(this, func, store, query).send();
return YES;
},
fetchDidComplete: {
'default': function(response, store, query) {
if (SC.ok(response)) {
//В зависимости от id берём нужные записи из полученного json
var body = this.urls[query.get('id')]['records'];
//Получаем тип записи
var recordType = query.get('recordType');
//Если тип не задан, значит их несколько и они хранятся в recordsTypes
if (!recordType) {
var recordTypes = query.get('recordTypes'); //Получаем типы записей
jQuery.each(body, function(i) {
//Загружаем в store записи разных типов. Порядок выдачи записей разных типов сервером
//и порядок этих типов в запросе должны совпадать. Т.е.:
//SC.Query.local[Scm.Product, Scm.Taxon] и {products: [{product1}, {product2}], taxons: [{taxon1}, {taxon2}]}
store.loadRecords(recordTypes[i], response.get('body')[body[i]]); });
}
else {
store.loadRecords(recordType, response.get('body'));
}
store.dataSourceDidFetchQuery(query);
} else store.dataSourceDidErrorQuery(query, response);
}
},
});
Комментариев нет:
Отправить комментарий