Dojo DnD Mover nó programaticamente
-
06-07-2019 - |
Pergunta
Gostaria de saber se existe uma maneira de mover o nó programaticamente no dojo Dnd? A razão é que eu gostaria de reverter as alterações para o arrastar e soltar quando a chamada de serviço web desencadeou uma resistência falha no banco de dados. Aqui está o que eu tenho até agora.
No meu código, o nó Id parece ser reconhecido pela dojo.dnd.Container.DelItem. Eu não posso simplesmente usar o item selecionado no alvo porque esta é uma chamada de retorno função webservice assíncrona. Assim, o usuário pode ser selecionando outro nó no recipiente quando este é chamado.
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;
}
}
}
/**
* 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;
}
Solução
Parece que você assumir que delItem
remove nós físicos. Dê uma olhada na documentação - provavelmente você deseja mover nodos entre recipientes, em vez de eliminá-los a partir do mapa. Uma maneira simples de fazer isso apenas para movimento DOM nós entre recipientes, e sync()
chamada em ambos os recipientes.
Adição : Aqui é um super-simples pseudocódigo-como exemplo:
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();
}
Ou algo nesse sentido deve funcionar. As peças importantes:
- nó Mover de um pai para outro usando quaisquer operações DOM você considerem adequadas. Eu costumava
appendChild()
, mas você pode usarinsertBefore()
, ou qualquer outra coisa. - Sincronizar tanto fontes envolvidas depois da jogada.
Obviamente ele funciona se ambas as fontes usar os nós do mesmo tipo e estrutura. Se não, você deve fazer algo mais complexo, por exemplo, mover tudo que você precisa emular um DnD movimento real, através da publicação de temas descritos na documentação.
Outras dicas
Eu tenho essa função que move nós selecionados por clique de botão:
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()
é um método substituível, que é chamado a queda item, e por chamadas padrão para onDropExternal(source, nodes, copy)
método.
Eu estou fazendo a mesma coisa agora. Eu era capaz de resolver, fazendo o seguinte.
- Defina o DND / Fonte Autosync propriedade para true
<div data-dojo-type="dojo.dnd.Source" accept="widget" class="source" data-dojo-props="autoSync: true">
Depois de arrastar ele perde o dndtype então eu tive que re-adicioná-lo usando o código do lado do cliente. Também eu remover a classe dojoDndItemAnchor após queda.
$(node).removeClass('dojoDndItemAnchor').attr('dndtype', 'widget');