2010-10-25 4 views
3

У меня есть jqgrid (версия 3.5.3) на моем сайте, который получает результаты от вызова ajax веб-службе. Часто запрос сложный, и для загрузки результата требуется несколько секунд. Во время загрузки пользователь видит поле [Загрузка ...].Как добавить кнопку отмены в jqgrid?

В случае пользователи понимают, что они ищут неправильные вещи, клиент попросил добавить кнопку отмены на сетке, которая:

  1. сделать сетки забыть о данных, это просто запрошенной
  2. сохранить результаты уже загружены из предыдущего поиска

Там, кажется, не будет ничего построено в для этого, так что я, вероятно, ищет немного хак для достижения этой цели.

Любые идеи?

+0

Это будет больше, чем «немного взломать». Самая большая проблема - это отмена запроса на сервер. Если вам удастся определить, будет ли запрос проходить долгое время, возможно, вам удастся предотвратить длительный запрос. В любом случае, это большая работа, даже если отмена запроса возможна. – Gregg

ответ

0

Вот наше решение, которое очень похоже на Олега, основное отличие состоит в том, что мы отслеживаем список XHR следует, чтобы убедиться, что мы убираем все запросы до

var handlerUrl = ''; 

jQuery(document).ready(function() { 
    var xhrList = []; 

    var beforeSendHandler = function() { 

     var cancelPendingRequests = function() { 
      jQuery.each(xhrList, function() { this.abort(); }); 
      xhrList = []; 
      return false; 
     }; 

     var hideLoadingUI = function() { 
      $(this).hide(); 
      $("#load_list").hide(); 
     }; 

     cancelPendingRequests(); 

     $("#load_list").show(); 

// some faffing around to ensure we only show one cancel button at a time 
     if (jQuery("#cancelrequest").length == 0) { 
      jQuery(".ui-jqgrid-titlebar").append(jQuery("<button id='cancelrequest'>Cancel</button>").click(cancelPendingRequests).click(hideLoadingUI)); 
     } else { 
      jQuery("#cancelrequest").show(); 
     }; 
    } 


    jQuery("#list").jqGrid({ 
     datatype: function(postdata) { 

      GetSearchCriteria(); //needed for the grid's filtering 

      var xhr = $.ajax({ 
       //we override the beforeSend so we can get at the XHRs, but this means we have to implement the default behaviour, like showing the loading message ourselves 
       beforeSend: beforeSendHandler, 
       dataType: "xml", 
       data: postdata, 
       success: function(xmlDoc) { 
        // 
        jQuery("#cancelrequest").hide(); 
        $("#load_list").hide(); 
        jQuery("#list")[0].addXmlData(xmlDoc); 
        xhrList = []; 
       } 

...

2

В общем $.ajax запрос возвращается XMLHttpRequest объект имеющий abort способ. Таким образом, если соответствующий вызов $.ajax будет иметь следующий вид:

var lastXhr = $.ajax ({ 
    // parameters 
    success:function(data,st) { 
     // do something 
     lastXhr = null; 
    }, 
    error:function(xhr,st,err){ 
     // do something 
     lastXhr = null; 
    } 
}); 

и мы имели бы доступ к lastXhr ценным тогда мы могли бы быть в состоянии назвать lastXhr.abort(). Я думаю, что новый метод, например, abortAjaxRequest в jqGrid, может быть лучшим решением.

без изменения текущего исходного кода jqGrid решения может выглядит следующим образом

var lastXhr; 
var stopAjaxRequest(myGrid) { 
    $('#cancel').attr('disabled', true); // disable "Cancel" button 
    lastXhr = null; 
    myGrid[0].endReq(); 
}; 
var grid = $("#list"); 
grid.jqGrid ({ 
    // all standard options 
    loadComplete() { 
     stopAjaxRequest(grid); 
    }, 
    loadError() { 
     stopAjaxRequest(grid); 
    }, 
    loadBeforeSend (xhr) { 
     l$('#cancel').attr('disabled', false); // enable "Cancel" button 
     lastXhr = xhr; 
    } 
}); 

$("#cancel").click(function() { 
    if (lastXhr) { 
     lastXhr.abort(); 
    } 
}); 

В коде я полагаю, что у нас есть кнопка «Отмена» с идентификатором = «отменить» вне jqGrid , Я должен упомянуть, что я еще не тестировал код выше, но я надеюсь, что он должен работать.

Вы должны понимать, что приведенный выше код прерывает только ожидание браузера на стороне клиента, и процесс на сервере будет продолжен. Если ваш сервер будет выполнять прерывание на стороне сервера, то код выше не понадобится, и вы сможете напрямую вызвать этот метод прерывания сервера.

+0

Спасибо за всесторонний ответ! Мы закончили реализацию чего-то подобного, я, вероятно, опубликую это, когда мы его убрали –

+0

В версии 4.5.4 endReq() вызывается как: myGrid [0] .grid.endReq(); –

+0

@AlexeyF: Ответ был написан почти 4 года назад. С тех пор в jqGrid много изменений. 'endReq' перемещается в' myGrid [0] .grid.endReq() '(см. [строки] (https://github.com/tonytomov/jqGrid/blob/v4.6.0/js/grid.base.js # L2927-L2928) кода jqGrid) – Oleg

Смежные вопросы