Как выделить функциональность обратных вызовов из этой функции AJAX? - PullRequest
1 голос
/ 11 августа 2011

Я создал повторно используемый шаблон ajax в jQuery. Это работает хорошо, но начинает становиться грязным, когда я добавляю к нему больше действий.

Посмотрите на 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 ]

5 голосов
/ 11 августа 2011

Создайте карту «действий», сохраняя идентификатор действия и 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); и затем обратные вызовы получат ссылку в качестве параметра.

1 голос
/ 11 августа 2011

Мне нравится использовать переключатель для этого.

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;
}

Обратите внимание, что первый найденный элемент будет выполняться, пока у вас есть перерыв.

Альтернативный способ:Затем обратите внимание на response.success и NEED для перерывов.

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;
    }
1 голос
/ 11 августа 2011

Может быть, вы могли бы поместить все обратные вызовы в отдельный объект:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...