2016-08-17 9 views
2

В моем приложении много вызовов AJAX, каждый из которых возвращает ответ JSON. Вместо проверки данных в каждом вызове .done() я пытаюсь выполнить сжатие кода.JQuery AJAX - Фильтр перед .done()

Что мы имеем до сих пор

$.ajax({ 
    url: 'test', 
    type: 'GET', 
    data: { 
     _token: token 
    }, 
    dataFilter: function(jsonResponse) { 
     return isValidJson(jsonResponse); 
    } 
}).done(function(jsonResponse) { 
    // do things 
}); 

isValidJson(jsonResponse) { 
    try { 
     var parsedJson = $.parseJSON(jsonResponse); 

     if (parsedJson.error == 1) { 
      notificationController.handleNotification(parsedJson.message, 'error'); 

      return false; 
     } 
    } catch (err) { 
     notificationController.handleNotification('A server-side error occured. Try refreshing if the problem persists.', 'error'); 

     return false; 
    } 

    return jsonResponse; // Have to return the original data not true 
} 

Ожидаемое поведение является то, что если dataFilter возвращает ложь, это вызовет .fail(), если она возвращает истину, то он будет продолжать .done(). Вместо этого он просто продолжает .done() с результатом isValidJson().

Есть ли способ сделать .fail() сделать что-то стандартное, как отправить уведомление пользователю без необходимости ставить его под любой вызов AJAX?

+1

Нет «функции _А, которые будут использоваться для обработки данных необработанных отклика XMLHttpRequest Это предварительная фильтрация функции для дезинфекции ответа. ** Вы должны вернуть обработанные данные ** ._ ". Поэтому вы не должны возвращать TRUE FALSE, если проверка json в порядке или нет. ваш страттерг ошибается –

+0

@RoyiNamir Спасибо за это. Вы знаете правильный способ фильтрации данных вне .done() для всех вызовов AJAX? Должен ли я что-то продлить? –

+1

Вы пробовали это var jxhr = $ .ajax (dataFilter: function() {jxhr.abort()}); ? – Kison

ответ

2

Самый простой способ создать сокращение для $ .ajax, расширяя его.

Расширение вызова AJAX

jQuery.extend({ 
    myAjax: function(params){ 
     // Here we can modify the parameters and override them e.g. making 'error:' do something different 
     // If we want to add a default 'error:' callback 
     params.error = function() { 
      console.log('its failed'); 
     }; 

     // or you can specify data parse here 
     if (params.success && typeof params.success == 'function') { 
      var successCallback = params.success; 
      var ourCallback = function(responseJson) { 
       if (isValidJson(responseJson)) { // Validate the data 
        console.log('The json is valid'); 
        successCallback(responseJson); // Continue to function 
       } else { 
        console.log('The json is not valid'); 
       } 
      } 

      params.success = ourCallback; 
     } 

     return $.ajax(params); 
    } 
}); 

Теперь каждый раз, когда вы хотите сделать вызов AJAX в вашем приложении, вы НЕ использовать $ .ajax ({}). Вместо этого вы используете $ .myAjax ({});

Пример

$.myAjax({ 
    url: 'domain.com', 
    type: 'GET', 
    success: function(data) { 
     // Do what you'd do normally, the data here is definitely JSON. 
    }, 
    error: function(data) {} 
}); 

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

+1

ну, есть два обратных вызова. 'error' в $ .ajax и' fail' в объекте xhr. Я пытался установить неудачу $ .ajax. Отредактировал свою скрипку, теперь она работает.https://jsfiddle.net/drnuz676/6/ –

1

Попробуйте сделать это, как это (Not tested):

var jxhr = $.ajax({ 
    url: 'test', 
    type: 'GET', 
    data: { 
     _token: token 
    }, 
    dataFilter: function(jsonResponse) {   
     if (!isValidJson(jsonResponse)) { 
      jxhr.abort(); 
     } 
     return jsonResponse; 
    } 
}).done(function(jsonResponse) { 
    // do things 
}); 
+0

Вы нарушаете принцип разделения интересов. Почему действие A должно возвращать false из-за действия B? Действие A должно возвращать true, а позже, если хотите, возвращает false для действия B. –

+0

@Kison .abort() по-прежнему вызывает .done(). Если это сработает, будет ли способ автоматически применить его ко всем будущим аякс-запросам? –

+0

@RoyiNamir вы правы, нужно думать о более правильном пути, как это сделать – Kison

1

Используя эту стратегию, вы нарушаете стратегию "разделяй беспокойство".

Ajax должен разрешить или отклонить в соответствии с его действием. Не соответствует, если ответ JSON или нет.

Возможное решение:. (Уверен, что есть также еще растворы)

function GetSanitized(d) { 
    return d.then(function(a) { 
      if (a.indexOf('{') > -1) //check if json (just for example) 
       return $.Deferred().resolve(JSON.parse(a)); //return object 
      else 
       return $.Deferred().reject(a); //reject 
     }, 

     function() { 
      return $.Deferred().reject("ajax error"); //ajax failed 
     } 

    ); 
} 

var ajax = $.Deferred(); 

GetSanitized(ajax) .then(function (a){alert(" Json p's value is "+a["p"]);},function (a){alert("Error"+a);}); 


ajax.resolve("{\"p\":2}"); //simulate ajax ok , valid json 
//ajax.resolve("\"p\":2}"); //simulate ajax ok , invalid json 
//ajax.reject("\"p\":2}"); //simulate ajax bad , valid json 

http://jsbin.com/vozoqonuda/2/edit

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