Javascript wait for extern ajax request

2019-09-06 20:36发布

问题:

I've made a simple scroll content loading feature based on primefaces datatable:

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
    } 
});

Explanation: When a user scrolls down to the bottom of the dataTable, I just use the pagination, but save the old rows before. After finishing the pagination, I add the rows again. This leaves to a super cool scroll based loading, where only new data needs to be loaded from the server, and not the old content again.

But as I read in other questions, using synchronized ajax calls is bad practice.

It's not easy to override the "t.paginator.setPage(x)" function, because in this function there is anywhere an ajax call.

Is there a way, to wrap that whole function, and add some success callback to it, without digging down to the real basic ajax call?

Thanks a lot!

回答1:

You can have setPage return the $.ajax promise and do what you need in a promise callback.

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

Then when you call it do:

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


回答2:

Here is my solution: Because i needed to get access to paginator onsuccess or oncomplete method i now use the given ajax listener of the primefaces dataTable. The whole code for a scroll based content load system looks like this:

<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>