2011-08-10 89 views
1

我在jQuery中创建了一个可重用的ajax模式。它运作良好,但随着我添加更多操作,它开始变得混乱。如何从这个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的新手。

回答

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);的操作,然后让回调接收链接作为参数。

+1

我建议使用名称(而不是数字)标识函数,并将链接和响应传递给回调,以便您可以使用它们。就像:http://jsfiddle.net/Lobstrosity/kQtTV/ – Lobstrosity

+0

确实,我在想同样的事情,但它会让答案更长,可能只是一件好事。我们甚至不知道问题的代码是真实的还是仅仅是一个例子 –

+0

@Lobstrosity和Pablo,谢谢你们。我想我可以将标记更改为''谢谢。 – Mohamad

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) 
+0

谢谢。来自你和上面的巨大回应。 – Mohamad

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

请注意,只要您在那里休息,就会执行第一项为真的项目。

备选方法:记下response.success和break的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; 
    }