2017-02-16 5 views
0

Я сделал простую функцию загрузки содержимого прокрутки, основанный на primefaces DataTable:Javascript ждать запроса экстерном АЯКС

PF('tableWidget').jq.bind("scrollstop", function() { 
    var t = PF('tableWidget'); 
    if(t.jq.scrollTop() + t.jq.height() >= t.jq.children().height()) { 
     var rows = t.jq.find('tr');      //save current rows 
     $.ajaxSetup({async: false});      //ajax set sync 
     t.paginator.setPage(t.paginator.cfg.page + 1); //framework pagination function with an ajax call inside (and other stuff) to get new rows 
     rows.prependTo(t.jq.find('tbody'));    //AFTER pagination, add old rows 
     $.ajaxSetup({async: true});      //ajax set async again 
    } 
}); 

Объяснение: Когда пользователь прокручивает вниз к нижней части DataTable, я просто использовать пагинацию , но сохраните старые строки раньше. Закончив разбивку на страницы, я снова добавляю строки. Это приводит к загрузке супер классной прокрутки, где только новые данные должны быть загружены с сервера, а не старое содержимое снова.

Но, как я читал в других вопросах, использование синхронных вызовов ajax - это плохая практика.

Непросто переопределить функцию «t.paginator.setPage (x)», потому что в этой функции есть где-нибудь вызов ajax.

Есть ли способ обернуть эту целую функцию и добавить к ней некоторый успешный обратный вызов, не копаясь до реального базового вызова ajax?

Большое спасибо!

ответ

0

Вы можете иметь setPage, чтобы вернуть обещание $ .ajax и сделать то, что вам нужно, в обратном вызове обещания.

t.paginator.setPage = function(pageNum){ 
    // return the promise 
    return $.ajax(....); 
}; 

Затем, когда вы называете это сделать:

t.paginator.setPage(t.paginator.cfg.page + 1).then(function(){ 
    rows.prependTo(t.jq.find('tbody')); 
}); 
+0

Спасибо за этот ответ, но здесь вы переопределяете функцию setPage. Он уже реализован в среде с множеством различных вызовов функций, одним из которых является вызов ajax. Невозможно ли обернуть функцию setPage и получить событие вызова ajax? Скажем, с некоторой привязкой или чем-то еще. – kaiser

+0

Нет, не совсем ... это характер асинхронного кодирования. Вы можете попробовать использовать глобальный метод, например '$ (document) .ajaxSuccess()', и проверить используемый url или какой-либо другой параметр, который указывает, что он связан с пейджером. – charlietfl

+0

спасибо, я уже пытался связать ajaxSuccess с dataTable (родительский элемент paginator), но событие не запускается. – kaiser

0

Вот мое решение: Потому что мне нужно, чтобы получить доступ к Paginator OnSuccess или OnComplete метода я теперь использовать данный АЯКС слушатель primefaces DataTable , Весь код для системы загрузки содержимого на основе прокрутки выглядит следующим образом:

<p:dataTable id="table" value="#{items}" var="item" paginator="true" widgetVar="tableWidget"> 
    <p:ajax event="page" onstart="storeRows()" oncomplete="restoreRows()"/> 
    ... 
</p:dataTable> 

<h:outputScript> 
    <!-- variables --> 
    var rows; 

    <!-- scroll bottom to load more --> 
    PF('tableWidget').jq.bind("scrollstop", function() { 
     var t = PF('tableWidget'); 
     if(t.jq.scrollTop() + t.jq.height() >= t.jq.children().height()) { 
      t.paginator.setPage(t.paginator.cfg.page + 1); 
     } 
    }); 

    <!-- store and restore rows --> 
    function storeRows() { 
     var t = PF('tableWidget'); 
     rows = t.jq.find('tr'); 
    } 

    function restoreRows() { 
     var t = PF('tableWidget'); 
     rows.prependTo(t.jq.find('tbody')); 
    } 
</h:outputScript> 
Смежные вопросы