简体   繁体   中英

Separation of concerns and JQuery AJAX callbacks

I am working on a web application for debtor management and I am refactoring the code and try to adhere to the principle of separation of concerns. But the async nature of AJAX is giving me headaches.

From a jQuery dialog the user can set a flag for a debtor which is then stored in a database. If that succeeds, the dialog shows a notification. Until now I handled everything inside the jQuery Ajax success callback function: validating input, doing the ajax request and updating the content of the dialog.

Of course this lead to spaghetti code.

Thus I created a class AjaxHandler with a static method for setting the flag, which is invoked by the dialog. I thought that the dialog could update itself according the the return value of the AjaxHandler but I did not have the asynchronity in mind.

The following question was helpful in tackling the return values.

How do I return the response from an asynchronous call?

But how can I update the dialog without violating the SoC principle?

EDIT

$("#button").on("click", function() {
    var returnValue = AjaxHandler.setFlag();
    if(returnValue) { $("#div").html("Flag set"); }
    else { $('#div").html("Error setting flag");
});

class AjaxHandler { 
    static setFlag(){
        $.ajax({
            type: "POST",
            url: "ajax/set_flag.php",
            success: function(returndata){
            return returndata; //I know this does not work because of                         
            //ASYNC,but that is not the main point.                                                                        


        }
        }
    })

Consider using events perhaps here?

 $("#button").on("click", function() { $('body').trigger('getdata', ["", $('#div')]); }); $('body').on('getdata', function(event, datasent, myelement) { var attach = event.delegateTarget;// the body here var getAjax = $.ajax({ type: "POST", url: "ajax/set_flag.php", data: datasent // in case you need to send something }) .done(function(data) { $(attach).trigger('gotdata', [data, myelement]); }); getAjax.fail(function() {}); }) .on('gotdata', function(event, datathing, myelement) { myelement.html(!!datathing ? "Flag set", "Error setting flag"); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 

Note that inside those event handlers you could also call some function, pass a namespace for the function, basically do it as you please for your design.

There is many ways to handle async responses, but the jQuery way is slightly different, so when you are already using jQuery, handle it this way:

$('#button').on('click', AjaxHandler.setFlag)

class AjaxHandler {
  static setFlag () {
    this.loading = true
    this
      .asyncReq('ajax/set_flag.php')
      .done(function () {
        $('#div').html('Flag set')
      })
      .fail(function (err) {
        $('#div').html('Error setting flag. Reason: ' + err)
      })
      .always(function () {
        this.loading = false
      })
  }

  asyncReq (url) {
    return $.ajax({
      type: 'POST',
      url: url
    })
  }
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM