2010-09-29 104 views
6

我有這個有趣的jQuery函數。它基本上增加了一個點擊處理程序來鏈接,當點擊時,它會加載一個表單以允許用戶編輯內容。並且表單由AJAX提交,並在完成時顯示成功消息。JQuery/JavaScript:重構嵌套函數

大綱如下;不用說,這是混亂的。我可以將每個回調作爲一個類方法。還有什麼其他方式來重構嵌套函數?我也有興趣,看看是否有辦法的變量在父函數聲明仍保留其值下降到嵌套函數的重構

$('a.edit').click(function() { 

    // ..snipped.. 
    // get form 
    $.ajax({ 
     success: function() { 

     // add form 
     // submit handler for form 
     $(new_form).submit(function() { 

      // submit via ajax 
      $.ajax({ 

       success: function(data) { 
        // display message 
       } 
      }) 

     }) 

     }} 
    ) 
} 

回答

4

我想你的問題有趣的部分是如何重構,而不會失去對閉包變量的訪問。這裏是我的建議:

版本之一:嵌套,以封鎖和變量訪問:

var a; 
    $('a.edit').click(function() { 
     var b; 
     $.ajax({ 
     success: function() { 
      var c; 
      $(new_form).submit(function() { 
      var d; 
      $.ajax({ 
       success: function(data) { 
        // a,b,c,d are all visible here. 
        // note that a references the same object for all calls of the success function, whereas d is a different variable for each call of submit. 
        // this behaviour is called closure: the 'enclosed' function has access to the outer var 
       } 
      }) 
      }) 
     } 
     }) 
    }) 

版本二:不嵌套的,但沒有封鎖和不變量訪問:

var a; 
$('a.edit').click(onEdit); 

var onEdit = function() { 
    var b; 
    $.ajax({success: onEditSuccess}); 
}; 

var onEditSuccess = function() { 
    var c; 
    $(new_form).submit(onSubmit); 
}; 

var onSubmit = function() { 
    var d; 
    $.ajax({success: onSubmitSuccess}); 
} 

var onSubmitSuccess = function(data) { 
    // a is visible (global var) 
    // b,c,d NOT visible here. 
}; 

第三版:嵌套較少並且具有未命名的函數和參數以訪問閉合變量:

var a; 
$('a.edit').click(function(){onEdit(a)}); 

var onEdit = function(a) { 
    var b; 
    $.ajax({success: function(){onEditSuccess(a,b)}}); 
}; 

var onEditSuccess = function(a,b) { 
    var c; 
    $(new_form).submit(function(){onSubmit(a,b,c)}); 
}; 

var onSubmit = function(a,b,c) { 
    var d; 
    $.ajax({success: function(data){onSubmitSuccess(data,a,b,c,d)}}); 
} 

var onSubmitSuccess = function(data,a,b,c,d) { 
    // a,b,c,d are visible again 
    // nice side effect: people not familiar with closures see that the vars are available as they are function parameters 
}; 
1

您可以輕鬆地重構這個,使其更具可讀性之後。要掌握的關鍵概念是,您可以在回調中引用命名函數以及匿名函數。所以,舉例來說:

function clickHandler() { 
    alert("Link clicked"); 
} 
$('a').click(clickHandler); 

我的選擇是總是根據他們所做的事情(例如loadImage給予函數的名稱,而不是事件,你打算觸發它們(如clickLink這使你的代碼更清晰,使得後來的變化更容易在這種情況下,我會組織我這樣的代碼:。

$(document).ready(function(){ 
    $('a.edit').click(loadFormStart); 

    function loadFormStart() { // get form 
     $.ajax({ 
      success: loadFormEnd 
     }); 
    } 

    function loadFormEnd(data) { // add form & handler 
     $('new_form').submit(handleFormStart); 
    } 

    function handleFormStart() { // submit form 
     $.ajax({ 
      success: handleFormEnd 
     }); 
    } 

    function handleFormEnd(data) { // receive form data 
     //display message 
    } 
}); 

我還建議你閱讀Code Organization on jqfundamentals這給類似的方法來此使用對象文本

0

有趣的問題。我個人不介意以上。評論是關鍵,所以你可以考慮用一些排位賽結束括號:

  } //success: function(data) 
     }) //$.ajax({ 
    }) //$(new_form).submit(

...等

我也想看看正確對準支架(在第一clance,你}}有點神祕)。

如果涉及到「通用」嵌套策略,我唯一的建議是將代碼移出其他函數。當然,這意味着你的內存中有功能被剝離,但可能會使其更具可讀性。

您也可以考慮與此代碼相關的特定策略。例如,不是手動綁定submitnew_form,您能否以某種方式使用live函數來確保它是自動完成的?

在完全不相關的說明中,您應該在每個括號內的行尾添加一些;

+0

Re使用$()。live() - 要小心,因爲提交事件在Internet Explorer中不會冒泡。據說jQuery修復了這個問題,但是我發現我不得不綁定到submit按鈕的click事件,這顯然不是最好的解決方案。 – lonesomeday 2010-09-29 08:42:03

+0

我總是遠離過度嵌套的構造。再加上任何體面的IDE都不需要記錄右括號,看起來真的很醜! – 2011-05-05 16:41:21