2013-01-11 26 views
1

我相信我已經想出了我的代碼中的循環閉包問題。我讀過this article 這是一個很大的幫助。最近,我提出了一個類似於文章中引用的「循環閉合」部分的問題。我試過他們的解決方案,但它仍然沒有解決我的問題。我一直在尋找解決方案,但我總是在文章中找到它。使用封閉循環:不工作? (使用jqueryui)

我正在使用jqueryui使一些lis可拖動,當我把它們放在容器中時,我需要使用特定於該li的變量(節點)。問題是節點(和索引)總是最後一個(因此關閉問題)。

這裏是我的代碼(我已經簡化它一點點,使其更易於識別問題):

function makeDraggable(node, i) { 
     $("#rightTab li#" + node.id).draggable({ 
      containment: 'div#container', 
      stack: 'div#container', 
      scroll: false, 
      revert: 'invalid', 
      helper: function() { 
       return $(this).children().clone(); 
      }, 
      start: function(event, ui) { 
       $(this).children().css('opacity', 0); 
      }, 
      stop: function(event, ui) { 
       $(this).children().css('opacity', 1); 
      } 
     }); 

     $("#vis").droppable({ 
      drop: test(node, i) 
     }); 
    } 

    function test(noder, index) { 
     return function(event, ui) { 
      alert(index); 
      //stuff with node. 
     } 
    } 

    function appendInfo(nodes) { 
     for(var i = 0; i < nodes.length; i++) { 
      $("#rightTab #content ul").append("<li id=" + nodes[i].id + "><div></div></li>"); 

      if(visualization.hasImageLabel) { 
       interfaceHandler.handleImageLabel(nodes[i]); 
      } 
      if(visualization.hasTextLabel) { 
       interfaceHandler.handleTextLabel(nodes[i]); 
      } 

      makeDraggable(nodes[i], i); 
     } 
    } 

當我提醒指數(功能試驗),它總是打印9 (最大數組長度),節點也總是最後一個。

(對不起,我英文不好)

回答

1

你打電話$("#vis").droppable({...})通過循環的每次迭代。這設置了10個drop事件處理程序;只有最後一個被觸發,它被傳遞(node_nine,9)作爲它的參數。

檢查回調中的ui.draggable的值;它會告訴你什麼是被丟棄的元素。

+0

哦,好吧。我現在感到非常愚蠢。出於某種原因,我認爲我必須爲每個可拖動的項目添加一個droppable,但這甚至沒有意義。非常感謝你的幫助。 – Solidus

+0

我們都在這裏學習:) –

-1

試試這個,添加一個內部變量,它會繼續查找變量i,直到for循環就被宣佈:

function makeDraggable(node, i) { 
    var innerIndex = i; 
    $("#rightTab li#" + node.id).draggable({ 
     containment: 'div#container', 
     stack: 'div#container', 
     scroll: false, 
     revert: 'invalid', 
     helper: function() { 
      return $(this).children().clone(); 
     }, 
     start: function(event, ui) { 
      $(this).children().css('opacity', 0); 
     }, 
     stop: function(event, ui) { 
      $(this).children().css('opacity', 1); 
     } 
    }); 

    $("#vis").droppable({ 
     drop: test(node, innerIndex) 
    }); 
} 
+1

我沒有被關閉,因爲它作爲參數傳遞來測試(...),所以使我的副本不做任何事情。 –

+0

@Jacob Krall你是對的,這是我的錯誤 – keshin

1

問題是$("#vis").droppable(...)取代了以前定義的可放置功能,因此不能用閉包來解決。

如果一定要知道該指數是重要的,然後嘗試使每個節點可拖動知道其自己的索引與.data(...),並在appendInfo()調用$("#vis").droppable(...)只有一次,而不是在makeDraggable()

function appendInfo(nodes) { 
    for(var i = 0; i < nodes.length; i++) { 
     $("#rightTab #content ul").append("<li id=" + nodes[i].id + "><div></div></li>"); 
     if(visualization.hasImageLabel) { 
      interfaceHandler.handleImageLabel(nodes[i]); 
     } 
     if(visualization.hasTextLabel) { 
      interfaceHandler.handleTextLabel(nodes[i]); 
     } 
     makeDraggable(nodes[i], i); 
     $(node).data('index', i); //<<< node is now aware of its own index 
    } 
    $("#vis").droppable({ 
     drop: function(event, ui) { 
      alert(ui.draggable.data('index'));//I think??? 
      //stuff with node. 
     } 
    }); 
} 

如果它沒有必要知道指數,那麼你可以只訪問作爲拖動ui.draggable,沒有設置或獲取.data()

+0

是的,這很有用,非常感謝。 Jacob Krall已經告訴過那個。出於某種原因,我認爲必須爲每個可拖動的內容添加droppable。哦,不要再爲我工作了。 – Solidus