admin管理员组

文章数量:1208155

I'm making many ajax call based web service. I attached event listeners every dom elements. And every event handlers request ajax call in it. By the way, my source code getting more dirty and complexity. I want to reduce boilerplate code and look more simple with ajax calls.

How can I do that effectively?

The sample code looks like this:

<a href="javascript:void(0);" class="button1">button1</a>
<a href="javascript:void(0);" class="button2">button2</a>
<a href="javascript:void(0);" class="button3">button3</a>
<a href="javascript:void(0);" class="button4">button4</a>

$('.button1').on('click', function() {
    $.ajax({
        url: '/api/1/resource1',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom1').html(Handlebars.resource({items:response.items}));
        }
    });
});

$('.button2').on('click', function() {
    $.ajax({
        url: '/api/1/resource2',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom2').html(Handlebars.resource({items:response.items}));
        }
    });
});

$('.button3').on('click', function() {
    $.ajax({
        url: '/api/1/resource3',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom3').html(Handlebars.resource({items:response.items}));
        }
    });
});

$('.button4').on('click', function() {
    $.ajax({
        url: '/api/1/resource4',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom4').html(Handlebars.resource({items:response.items}));
        }
    });
});

Updated:

Every class name and ajax response handler is not same each other. Example code just shows boilerplate code and complexity. This is not the problem of class name or if else statements.

I'm making many ajax call based web service. I attached event listeners every dom elements. And every event handlers request ajax call in it. By the way, my source code getting more dirty and complexity. I want to reduce boilerplate code and look more simple with ajax calls.

How can I do that effectively?

The sample code looks like this:

<a href="javascript:void(0);" class="button1">button1</a>
<a href="javascript:void(0);" class="button2">button2</a>
<a href="javascript:void(0);" class="button3">button3</a>
<a href="javascript:void(0);" class="button4">button4</a>

$('.button1').on('click', function() {
    $.ajax({
        url: '/api/1/resource1',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom1').html(Handlebars.resource({items:response.items}));
        }
    });
});

$('.button2').on('click', function() {
    $.ajax({
        url: '/api/1/resource2',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom2').html(Handlebars.resource({items:response.items}));
        }
    });
});

$('.button3').on('click', function() {
    $.ajax({
        url: '/api/1/resource3',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom3').html(Handlebars.resource({items:response.items}));
        }
    });
});

$('.button4').on('click', function() {
    $.ajax({
        url: '/api/1/resource4',
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom4').html(Handlebars.resource({items:response.items}));
        }
    });
});

Updated:

Every class name and ajax response handler is not same each other. Example code just shows boilerplate code and complexity. This is not the problem of class name or if else statements.

Share Improve this question edited Feb 24, 2015 at 6:30 gentlejo asked Feb 24, 2015 at 6:19 gentlejogentlejo 2,7105 gold badges27 silver badges31 bronze badges
Add a comment  | 

6 Answers 6

Reset to default 14

Make common function like this:

String.prototype.endsWith = function(suffix) {
   return this.indexOf(suffix, this.length - suffix.length) !== -1;
};

var doAjax_params_default = {
    'url': null,
    'requestType': "GET",
    'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
    'dataType': 'json',
    'data': {},
    'beforeSendCallbackFunction': null,
    'successCallbackFunction': null,
    'completeCallbackFunction': null,
    'errorCallBackFunction': null,
};


function doAjax(doAjax_params) {

    var url = doAjax_params['url'];
    var requestType = doAjax_params['requestType'];
    var contentType = doAjax_params['contentType'];
    var dataType = doAjax_params['dataType'];
    var data = doAjax_params['data'];
    var beforeSendCallbackFunction = doAjax_params['beforeSendCallbackFunction'];
    var successCallbackFunction = doAjax_params['successCallbackFunction'];
    var completeCallbackFunction = doAjax_params['completeCallbackFunction'];
    var errorCallBackFunction = doAjax_params['errorCallBackFunction'];

    //make sure that url ends with '/'
    /*if(!url.endsWith("/")){
     url = url + "/";
    }*/

    $.ajax({
        url: url,
        crossDomain: true,
        type: requestType,
        contentType: contentType,
        dataType: dataType,
        data: data,
        beforeSend: function(jqXHR, settings) {
            if (typeof beforeSendCallbackFunction === "function") {
                beforeSendCallbackFunction();
            }
        },
        success: function(data, textStatus, jqXHR) {    
            if (typeof successCallbackFunction === "function") {
                successCallbackFunction(data);
            }
        },
        error: function(jqXHR, textStatus, errorThrown) {
            if (typeof errorCallBackFunction === "function") {
                errorCallBackFunction(errorThrown);
            }

        },
        complete: function(jqXHR, textStatus) {
            if (typeof completeCallbackFunction === "function") {
                completeCallbackFunction();
            }
        }
    });
}

then in your code:

$('.button').on('click', function() {
  var params = $.extend({}, doAjax_params_default);
  params['url'] = `your url`;
  params['data'] = `your data`;
  params['successCallbackFunction'] = `your success callback function`
  doAjax(params);
});

Use a common class:

<a href="javascript:void(0);" class="button">button1</a>
<a href="javascript:void(0);" class="button">button2</a>
<a href="javascript:void(0);" class="button">button3</a>
<a href="javascript:void(0);" class="button">button4</a>

add listener to this class:

$('.button').on('click', function() {
//find the index of the element and use it 
    var btnNumber= $( ".button" ).index(this)+1;

    $.ajax({
        url: '/api/1/resource'+btnNumber,
        data: {
            value1: 'value1',
            value2: 'value2'
        },
        success: function (response) {
            $('.some_dom'+btnNumber).html(Handlebars.resource({items:response.items}));
        }
    });
});

You can also use any kind of attribute and use it later for any data or parameter

like :

<a href="javascript:void(0);" abc="hello1" class="button">button1</a>
<a href="javascript:void(0);" abc="hello2" class="button">button2</a>
<a href="javascript:void(0);" abc="hello3" class="button">button3</a>
<a href="javascript:void(0);" abc="hello4" class="button">button4</a>

and then use it for any purpose

$('.button').on('click', function() {
    var dVal=$(this).attr('abc');
//use dVal any where you want.
    alert(dVal);

});

You can follow this change:

<a href="javascript:void(0);" data-url="/api/1/resource1" class="button">button1</a>
<a href="javascript:void(0);" data-url="/api/1/resource2" class="button">button2</a>
<a href="javascript:void(0);" data-url="/api/1/resource3" class="button">button3</a>
<a href="javascript:void(0);" data-url="/api/1/resource4" class="button">button4</a>

Make use of data-* attribute to hold the specific url for each link which is going to be clicked. Now just one change and you would have a common click event for all ajax calls:

$('.button').on('click', function() {
  var url = $(this).data('url');
  var index = $(this).index();
  $.ajax({
    url: url,
    data: {
      value1: 'value1',
      value2: 'value2'
    },
    success: function(response) {
       $('.some_dom'+index).html(Handlebars.resource({items: response.items}));
    }
  });
});

As per your update in your question you can try doing this:

    success: function(response) {
       if(url.indexOf('1') != -1){
          $('.some_dom1').html(Handlebars.resource({items: response.items}));
       }else if(url.indexOf('2') != -1){
          $('.some_dom2').html(Handlebars.resource({items: response.items}));
       }else if(url.indexOf('3') != -1){
          $('.some_dom3').html(Handlebars.resource({items: response.items}));
       }
    }

In success you have to check if the current url of ajax call is having something different to other calls, so if that matches then you can differentiate it within the if/else if conditions.

You can give a common button class to all tags and you can have a single event handler. Then on the basis of other class name you can make calls using different url and data.

<a href="javascript:void(0);" class="button button1">button1</a>
<a href="javascript:void(0);" class="button button2">button2</a>
<a href="javascript:void(0);" class="button button3">button3</a>
<a href="javascript:void(0);" class="button button4">button4</a>


var  ajaxFunc = function(url, data, successFun){
     $.ajax({
        url: url,
        data:data,
        success: successFun
    });
}

$('button').on('click', buttonClick);


function buttonClick (){
    var elem = $(event.target),
        url='', data;
    if(elem.hasClass('button1')){
        url = '/api/1/resource1';
        data =  {
            value1: 'value1',
            value2: 'value2'
        }
        ajaxFunc(url, data, successFun1);
    } else if(elem.hasClass('button2')){
        url = '/api/1/resource2';
        data =  {
            value1: 'value1',
            value2: 'value2'
        }
        ajaxFunc(url, data, successFun2)
    } else if(elem.hasClass('button3')){
        url = '/api/1/resource3';
        data =  {
            value1: 'value1',
            value2: 'value2'
        }
        ajaxFunc(url, data, successFun3)
    }
     else if(elem.hasClass('button4')){
        url = '/api/1/resource4';
        data =  {
            value1: 'value1',
            value2: 'value2'
        }
        ajaxFunc(url, data, successFun4)
    }
}

function successFun1(evt){

}
function successFun2(evt){

}

If you are not doing anything different then you can go for only one success function.

The template for anchor tag can be like this

<a data-url="url" data-dataId="dataKey" data-success="functionName" onclick="ajax_call(this);">button</a>

or

<a href="javascript:void(0);" data-completeObj="completeObj" onclick="ajax_call(this);" class="button">button</a>

Then the javascript and jQuery part. Store all the parameters needed to pass for each request with a key, this key must match the html data attribute.

var myBigJsonObj = { 
    data1 : { "foo": "bar" }, 
    data2 : { "foo": "bar", "foo1": "bar1"}                   
};

A user defined success function. Similarly can have error function.

function success() {
    // Do some stuff here
    alert('Success');
}

Finally the ajax request call.

function ajax_call(obj) {
    var url = obj.getAttribute('data-url');
    var data = myBigJsonObj[obj.getAttribute('data-dataID')];
    var success = obj.getAttribute('data-success');

    $.ajax({
        url: url,
        data: data,
        success: window[success].call();
    });
}

You can make an async function that contains the ajax API call. Then from everywhere, you can simply call and use the 'then' method for success and error response implementation.

Like here I will give you a very basic example:

// req is JSON type
// SERVICE_URL is global declared service URL or you can pass it as an argument

async function apiCall(req) {
    var form_data = new FormData;
    for (var key in req) form_data.append(key, req[key]);

    let myPromise = new Promise(function (myResolve, myReject) {
        $.ajax({
            url: SERVICE_URL,
            type: 'POST',
            data: form_data,
            processData: false,
            contentType: false,
            success: function (result) {
                myResolve(result);
            },
            error: function (error) {
                myReject(error);
            }
        });
    });

    return await myPromise;
}

Then from everywhere where you are required to use this ajax call use in asynchronous way, like:

// form is the form reference passed from onsubmit method from HTML
// username & password are input fields with 'name' attribute as 'username' & 'password'

function saveForm(form) {
    event.preventDefault();

    const req = {
        username: form.username.value,
        password: form.password.value
    }

    apiCall(req,).then(
        function (value) { console.log('async success:', value) },
        function (error) { console.log('async error:', error) }
    )
}

This is a completely asynchronous implementation and since it's a common function hence is a most cleaner way to do it.

本文标签: javascriptHow can I make many jQuery ajax calls look prettyStack Overflow