Итак, я решил первый технический пост не посвящать азам Sencha Touch и не стал излагать тот минимум, который необходим для создания мобильного web приложения (об этом я расскажу в следующих записях), я хочу рассказать вам о компонентах Ext.List, Ext.util.Scroller, о AJAX-запросах и как с помощью этого всего сделать так, чтобы по достижению дна списка подгружалась следующая порция контента.
(на момент написания использовалась Sencha Touch 0.91 beta)
Когда передо мной возникла эта задача, я первым делом полез в документацию Sencha Touch (http://www.sencha.com/deploy/touch/docs/) и обнаружил, что никаких событий, связанных со скроллингом, у компонента Ext.List нет. Сразу после этого, я открыл исходники компонента List в поисках недокументированных возможностей (в ExtJS к этим махинация приходилось обращаться часто, поскольку стандартным набором API сделать можно далеко не всё, а вот если сделать Ext'овскому компоненту какой-нибудь адаптер, то функционал библиотеки можно существенно расширить). Покопавшись в коде, я обнаружил такой компонент, как scoller, оказавшийся на деле Ext.util.Scroller, у которого в документации уже присутствовали, необходимые мне, события:
(на момент написания использовалась Sencha Touch 0.91 beta)
Когда передо мной возникла эта задача, я первым делом полез в документацию Sencha Touch (http://www.sencha.com/deploy/touch/docs/) и обнаружил, что никаких событий, связанных со скроллингом, у компонента Ext.List нет. Сразу после этого, я открыл исходники компонента List в поисках недокументированных возможностей (в ExtJS к этим махинация приходилось обращаться часто, поскольку стандартным набором API сделать можно далеко не всё, а вот если сделать Ext'овскому компоненту какой-нибудь адаптер, то функционал библиотеки можно существенно расширить). Покопавшись в коде, я обнаружил такой компонент, как scoller, оказавшийся на деле Ext.util.Scroller, у которого в документации уже присутствовали, необходимые мне, события:
- scrollend - скроллирование окончено (то, что нам надо)
- scrollstart - скроллирование началось
- touchend - окончание прикосновения к экрану
- touchstart - начало прикосновения к экрану
Трудности возникли с самого первого пункта: в документации Sencha Touch отсутствовали методы или переменные для получения компонента Scroller. Пришлось открыть исходники Ext.List и, прибегнув к хаку, вручную извлечь, необходимый нам, скроллер:
Итак, мы подписались на события окончания скроллинга, и теперь необходимо извлечь данные о позиции скролла и данные о общей длинне скроллируемого листа, чтобы сравнить их. В событие scrollend передаётся экземпляр скроллера, из которого мы все эти данные и выпытаем:
scroller.offset.y - текущее положение скроллинга
scroller.bounds.y - общий размер скроллируемого списка
this.loadContent() - функция подгрузки нового контента
this.page - номер страницы
this.isLoading - флаг загрузки (необходим, чтобы нельзя было сто раз вызвать подгрузку новго контента, пока старый не загрузился)
Осталось вызвать Ajax-метод и добавить, подгруженный контент, к существующему:this.scroller.on('scrollend', this.onScrollEnd, this);(this - это сам наш List, а this.onScrollEnd - функция обработчика события)onScrollEnd: function(scroller) {
if(scroller.offset.y == scroller.bounds.y && !this.isLoading) {
this.isLoading = true;
this.loadContent(++this.page);
}
}
scroller.offset.y - текущее положение скроллинга
scroller.bounds.y - общий размер скроллируемого списка
this.loadContent() - функция подгрузки нового контента
this.page - номер страницы
this.isLoading - флаг загрузки (необходим, чтобы нельзя было сто раз вызвать подгрузку новго контента, пока старый не загрузился)
loadContent: function(page) {
Ext.Ajax.request({
/* адрес php-функции, подгружающей контент */
url : 'action.php',
method : 'POST',
/* список параметров, передаваемых в запрос */
params : {
/* номер страницы (если не определён, то берём страницу №1) */
page : page || 1
},
scope : this,
/* запрос прошёл успешно */
success : function(response, opts) {
/* декодируем строку в JSON-объект */
response = Ext.util.JSON.decode(response.responseText);
if(response.content != null) {
/* если не обнулить это свойство, то все новые записи будут дублироваться */
this.getStore().snapshot = null;
/* пробегаем по всем записям */
Ext.each(response.content, function(entry) {
/* добавляем запись в Store */
this.getStore().add(entry);
}, this);
}
/* разрешаем подгрузку следующей порции контента */
this.isLoading= false;
},
/* запрос не прошёл */
failure : function(response, opts) {
this.isLoading= false;
}
});
}
Вот, в принципе, и всё. Теперь, когда вы прокрутите список в самый низ, будет подгружаться новая порция контента. Не забудьте правильно сконфигурировать сам Ext.List и его Ext.data.Store (об этом я расскажу в следующих записях).
self.getScrollable().getScroller()
ОтветитьУдалитьВерсия была 0.91 beta - с тех пор многое поменялось.
ОтветитьУдалить