質問

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');

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top