2009-11-28 55 views
2

我想知道是否有方法在dojo Dnd中以編程方式移動節點?原因是我想恢復對Web服務調用觸發數據庫失敗保存時拖放的更改。這是我到目前爲止。Dojo DnD以編程方式移動節點

在我的代碼中,節點Id似乎無法被dojo.dnd.Container.DelItem識別。我不能只在目標上使用選定的項目,因爲這是一個異步的web服務函數回調。所以當這個被調用時,用戶可能正在選擇容器上的另一個節點。

function OnMoveWSComplete(strResult) { 
    var resultObj = eval('(' + strResult + ')'); 
    var sourceContainer = eval('(' + objResult.sourceContainerId + ')'); 
    var targetContainer = eval('(' + objResult.targetContainerId + ')'); 

    var targetNodes = targetContainer.getAllNodes(); 
    for (var iNode = 0; iNode < targetNodes.length; iNode++) { 
     var currId = getLastIdFromStr(targetNodes[iNode].id); 

     if (currId == resultObj.Id) { 
      var targetN = targetNodes[iNode]; 

      var Name = targetNodes[iNode].childNodes[0].nodeValue; 

      targetContainer.delItem(targetNodes[iNode].id); 
      var origData = { Id: resultObj.Id, Name: Name }; 
      sourceContainer.insertNodes(true, origData); 

      break; 
     } 
    } 
} 

編輯:解決方案(感謝尤金Lazutkin)[2009/11/30]:

/** 
* Move one node from one container to the other 
*/ 
function moveNode(nodeId, sourceContainer, targetContainer) { 
    var node = dojo.byId(nodeId); 

    // Save the data 
    var saveData = sourceContainer.map[nodeId].data; 

    // Do the move 
    sourceContainer.parent.removeChild(node); 
    targetContainer.parent.appendChild(node); 

    // Sync the DOM object → map 
    sourceContainer.sync(); 
    targetContainer.sync(); 

    // Restore data for recreation of data 
    targetContainer.map[nodeId].data = saveData; 
} 
+0

你怎麼祈求的OnMoveWSComplete免打擾完成後?我創建了一個適用於/ dnd/drop的函數,但是當它被調用時,DnD還沒有創建,所以更改的反向失敗。你能給我一個調用的例子嗎? 謝謝。 何塞 – 2010-05-19 13:36:14

+0

何塞,當我承認我剛剛使用連接的Dnd drop事件。它適用於我。 dojo.connect(containerId,'onDrop',onDropSave); – Nap 2010-05-20 06:39:26

回答

3

看起來你認爲delItem刪除物理節點。看看documentation —可能你想在容器之間移動節點,而不是從地圖上刪除它們。一個簡單的方法就是在容器之間移動DOM節點,並在兩個容器上調用sync()

加成:這裏是一個超級簡單的僞類例如:

function move(node, source, target){ 
    // normalize node and/or node id 
    node = dojo.byId(node); 
    // move it physically from one parent to another 
    // (from target to source) adding to the end 
    target.parent.appenChild(node); 
    // now it is moved from source to target 
    // let's synchronize both dojo.dnd.Source's 
    source.sync(); 
    target.sync(); 
} 

還是什麼沿着這些路線應該工作。重要的部分:

  • 使用您認爲合適的任何DOM操作將節點從一個父節點移到另一個父節點。我用appendChild(),但你可以使用insertBefore(),或其他任何東西。
  • 同步移動後涉及的兩個源。

很顯然,如果兩個源都使用相同類型和結構的節點,它就可以工作。否則,您應該做更復雜的事情,例如,通過發佈文檔中描述的主題來移動您需要的所有模擬真實DnD動作。

+0

我其實也已經做過同步(),但它不起作用。順便說一句,如果刪除然後添加不建議,你可以指向我的移動功能?我在文檔中找不到任何功能。 – Nap 2009-11-30 00:40:32

+1

沒有特殊的API在源之間移動節點。你在我的回答(最後一句)中試過了我爲你勾畫的那個嗎?好的,我會添加一個例子。 – 2009-11-30 01:45:51

+0

我剛剛讀了sync的源代碼。看起來delItem()和sync()調用不起作用的原因是因爲delItem()從map中刪除,而sync()將實際的DOM節點複製回實際上否定delItem()的映射結構。 – Nap 2009-11-30 03:02:11

2

我有這個功能,通過點擊按鈕移動選定的節點:

source.forInItems(dojo.hitch(this, function(item, id, map) { 
    if (dojo.hasClass(id, "dojoDndItemAnchor")) { 
    target.onDrop(source, [ dojo.byId(id) ], false); 
    dojo.removeClass(id, "dojoDndItemAnchor"); 
    } 
})); 

onDrop()是一個重寫的方法,它是在物品掉落調用,並默認調用方法onDropExternal(source, nodes, copy)

0

我現在正在做同樣的事情。我能夠通過以下方式解決問題。

  • 設置免打擾/來源AUTOSYNC屬性爲true

<div data-dojo-type="dojo.dnd.Source" accept="widget" class="source" data-dojo-props="autoSync: true">

拖動它失去了dndtype,所以我不得不使用客戶端代碼將其重新添加後。此外,我刪除後dojoDndItemAnchor類。

$(node).removeClass('dojoDndItemAnchor').attr('dndtype', 'widget');