2011-08-10 37 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; 
    }