如何从这个ajax函数中分解出回调函数?

时间:2011-08-10 21:58:20

标签: jquery ajax design-patterns

我在jQuery中创建了一个可重用的ajax模式。它运作良好,但随着我添加更多动作,它开始变得混乱。

查看success回调。每次添加新动作时,条件逻辑都会变得更加混乱:if actionType == foo, then bar等......

$('.action-panel').delegate('a', 'click', function () {
    var link = $(this),
        actionTypeId = link.data('action-type-id'),

    // Do stuff, like getting the url from the link, etc...
    // Throttle multiple clicks

        $.ajax({ //[snip]

            beforeSend: function () {
                link.toggleClass('on');
            },
            error: function () {
                link.toggleClass('on');
            },
            success: function (response) {
                if (response.success) {
                    if (actionTypeId === 4) {
                        // do stuff for action 4
                    }
                    else if (actionTypeId === 2) {
                        // do stuff related to action 2
                    }
                    else if (actionTypeId === 3) {
                        // do stuff related to action 3
                    }
                    // More action types, etc...
                }
                else {
                    link.toggleClass('on');
                }
            // decide to show tooltip or not
            });
        // do some extra stuff like re-enable the link (throtled earlier)

我应该将ajax函数本身分解出来。但我无法想出一种方法将回调条件分离到它们自己的块/函数中,并传回结果。

有什么想法吗?请记住,我是JavaScript和jQuery的新手。

3 个答案:

答案 0 :(得分:5)

拥有这样的“操作”地图,保存操作ID并执行function

var actions = {

  '4' : function () {
    $('.fav-count').text(response.newcount);
    $('.fav-count').toggleClass('on');
  },

  '2' : function() {
    link.siblings('.liked').removeClass('on');
    link.siblings('.count').text(response.newcount);
  }
}

然后在您success回调中:

if (response.success) {
   actions[actionTypeId]();
}

请注意,您可能需要更改一些内容,因为link无法从回调中看到,但您可以执行actions[actionTypeId](this);之类的操作,然后让回调接收链接作为参数。< / p>

答案 1 :(得分:1)

也许您可以将所有回调放在一个单独的对象中:

var success_callbacks = {};
success_callbacks["2"] = function(response) {
    link.siblings('.liked').removeClass('on');
    link.siblings('.count').text(response.newcount);
};
success_callbacks["3"] = function(response) {
    link.siblings('.disliked').removeClass('on');
    link.siblings('.count').text(response.newcount);
};
success_callbacks["4"] = function(response) {
    $('.fav-count').text(response.newcount);
    $('.fav-count').toggleClass('on');
};

然后在成功处理程序中调用它们

$('.action-panel').delegate('a', 'click', function () {
    var link = $(this),
        actionTypeId = link.data('action-type-id'),

    // Do stuff, like getting the url from the link, etc...
    // Throttle multiple clicks

    // BEGIN AJAX
    $.ajax({
        context: this,
        dataType: 'json',
        url: url,

        beforeSend: function () {
            link.toggleClass('on');
        },
        error: function () {
            link.toggleClass('on');
        },
        success: function (response) {
            if (response.success) {
                success_callbacks[action-type-id](response);
            }
            else {
                link.toggleClass('on');
            }
        // decide to show tooltip or not
        });
    // do some extra stuff like re-enable the link (throtled earlier)

答案 2 :(得分:1)

我喜欢使用开关。

switch (actionTypeId) {
case 4:
    $('.fav-count').text(response.newcount);
    $('.fav-count').toggleClass('on');
    break;
case 2:
    link.siblings('.liked').removeClass('on');
    link.siblings('.count').text(response.newcount);
    break;
case 3:
    link.siblings('.disliked').removeClass('on');
    link.siblings('.count').text(response.newcount);
    break;
default:
    break;
}

请注意,只要您在那里休息,就会执行第一个找到true的项目。

备选方式:请注意response.success和NEED for breaks。

switch (true) {
    case !response.success:
        link.toggleClass('on'); 
        break;
    case actionTypeId===4:
        $('.fav-count').text(response.newcount);
        $('.fav-count').toggleClass('on');
        break;
    case actionTypeId===2:
        link.siblings('.liked').removeClass('on');
        link.siblings('.count').text(response.newcount);
        break;
    case actionTypeId===3:
        link.siblings('.disliked').removeClass('on');
        link.siblings('.count').text(response.newcount);
        break;
    default:
        break;
    }