Dojo DnD Move Nodeをプログラムで
-
06-07-2019 - |
質問
dojo Dndでプログラムでノードを移動する方法があるかどうか知りたいですか?その理由は、Webサービス呼び出しがデータベースへの保存に失敗したときに、ドラッグアンドドロップへの変更を元に戻したいからです。ここに私がこれまでに持っているものがあります。
私のコードでは、ノード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;
}
}
}
編集:解決策(Eugene 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;
}
解決
delItem
が物理ノードを削除すると想定しているようです。 ドキュメント <!>#8212;をご覧ください。おそらく、マップからノードを削除するのではなく、コンテナ間でノードを移動する必要があります。コンテナ間で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の動きをエミュレートするために必要なものをすべて移動します。
他のヒント
ボタンをクリックして選択したノードを移動するこの機能があります:
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)
を呼び出します。
今も同じことをしています。次の操作を行うことで解決できました。
- dnd / Source 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');