views:

96

answers:

1

I have a search page whose results are rendered in a SlickGrid. It is an ajax search that executes onkeyup, so it's possible for a search to be performed, the Slick.Grid instance's render to be called, and have another result come back before the first asynchronous render completes. I'd like to cancel the initial render as soon as the second ajax request comes back so that there aren't two render calls taking place at the same time.

EDIT WITH EXAMPLE:

Here's what I'm doing, with alerts in place to track the execution order.

function setupGrid() {
    slickDataView = new Slick.Data.DataView();
    slickGrid = new Slick.Grid(slickGridDiv, slickDataView.rows, slickGridColumns, slickGridOptions);
    slickDataView.onRowsChanged.subscribe(function(rows) {
      slickGrid.removeRows(rows);
      slickGrid.updateRowCount();
      slickGrid.render();
    });
    slickDataView.onRowCountChanged.subscribe(function(args) {
      slickGrid.updateRowCount();
      slickGrid.render();
    });
} 

function performSearch() {   
    jQuery.get('searchPage.php', {MODEL_ID: userInputField.val()},
      function(results) {
        slickDataView.beginUpdate();
        alert(1);
        slickDataView.setItems(results);
        alert(2);
        slickDataView.endUpdate();
      }
    );
}

setupGrid();
userInputField.keyup(function() { performSearch(); });

I get the following alerts in this sequence when I type two numbers into the userInputField text field in quick succession:

1
1
2
+1  A: 

There must be something else going on on your page. The example you listed is impossible - JavaScript execution is never interrupted by an event getting fired. The event just gets queued up and picked up by the event loop after the current code is done executing. What you would see in your example, is 1212.

You will want to throttle the AJAX calls and also to cancel the callbacks from the previous calls since your AJAX responses may come back out of order and the older search results can override the newer ones.

Tin
Small correction: it is possible only if the call to .setItems() throws an exception on the first Ajax call.
Tin
While Firefox doesn't complain, IE8 is giving the following exception the refreshIdxById method of DataView:Message: 'items.length' is null or not an objectLine: 65Char: 28Code: 0URI: http://localhost/javascript/slickgrid/slick.model.js
RenderIn
@Tin: I'm caching the XMLHttpRequest and aborting it before running a new search if it's in progress, but that didn't seem to prevent the dual-render. I'm looking into it further to see if I've got other issues in my code.
RenderIn
My guess would be that on the first Ajax call response you're not getting valid data back. Try logging "results" to the console.
Tin
@Tin: Thanks so much... you saved me a lot of time and hair pulling. IE seems to return an empty/null result when I canceled the XHR requests.
RenderIn
For future users who may stumble across this, it's worth noting that jQuery did not identify the aborted XHR request as errored -- it came back as successful, but with data = null. I tried switching to jQuery.ajax() with an explicit error function defined and it still sent these aborted XHRs to the success function.
RenderIn