Dojo DnD Переместить узел программно - PullRequest
2 голосов
/ 28 ноября 2009

Я хотел бы знать, есть ли способ программно переместить узел в Dojo Dnd? Причина в том, что я хотел бы отменить изменения в перетаскивании, когда вызов веб-службы вызвал неудачное сохранение в базе данных. Вот что у меня есть.

В моем коде идентификатор узла, кажется, не распознается dojo.dnd.Container.DelItem. Я не могу просто использовать выбранный элемент на цели, потому что это обратный вызов асинхронной функции веб-сервиса. Таким образом, пользователь может выбрать другой узел в контейнере, когда он вызывается.

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;
        }
    }
}

РЕДАКТИРОВАТЬ : Решение (спасибо Евгению Лазуткину) [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;
}

Ответы [ 3 ]

3 голосов
/ 29 ноября 2009

Похоже, вы предполагаете, что delItem удаляет физические узлы. Посмотрите документацию & mdash; возможно, вы хотите перемещать узлы между контейнерами, а не удалять их с карты. Один простой способ сделать это - просто переместить узлы 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, опубликовав темы, описанные в документации.

2 голосов
/ 28 мая 2012

У меня есть эта функция, которая перемещает выбранные узлы нажатием кнопки:

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 голосов
/ 04 апреля 2013

Я делаю то же самое прямо сейчас. Я смог решить, выполнив следующее.

  • Установите для свойства 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');

...