Этот вопрос неоднократно поднимался на SO, но не в последнее время, и приведенный здесь пример является более полным, чем другие, которые я видел. Лучшая реализация перетаскивания с деревом материалов - это , размещенное здесь на среде @ @ 1003 * inorganik .
Я клонировал StackBlitz здесь.
Однако моя проблема в том, что вы можете перемещать узлы, только если у вас есть хотя бы один дочерний элемент на узле. Например, если вы удалите все дочерние узлы из приложения, а затем попытаетесь добавить его обратно в приложение.
Отброшенный узел будет вставлен в родительский узел только в том случае, если у узла есть братья и сестры, в строке 232:
// insert node
const newSiblings = findNodeSiblings(changedData, nodeAtDest.id);
if (!newSiblings) return;
newSiblings.splice(relativeIndex, 0, nodeToInsert);
Мне кажется логичным, что решение будет отслеживать, если пользователь перемещал перемещенный узел над другим узлом, когда они его отбрасывали, а затем предположил, что пользователь хочет сделать подчиненный узел родительским, см. снимок экрана:
Мой вопрос: это лучший способ go решить эту проблему? Если да, то как отследить зависший узел с помощью Angular Drag Drop CDK?
ОБНОВЛЕНИЕ:
Эта функция частично работает. Я обновил StackBlitz здесь.
Я обновил dragHover
метод, основанный на других реализациях мат-дерева DnD, которые я нашел, который устанавливает режим вставки в зависимости от того, как далеко до справа пользователь перетаскивает наведенный узел:
dragHover(node: FileFlatNode) {
// untype the event
const newEvent: any = event;
const percentageX = newEvent.offsetX / newEvent.target.clientWidth;
if (percentageX > .25) {
this.dragNodeInsertToParent = true;
} else {
this.dragNodeInsertToParent = false;
}
if (this.dragging) {
clearTimeout(this.expandTimeout);
this.expandTimeout = setTimeout(() => {
this.treeControl.expand(node);
}, this.expandDelay);
}
}
Я добавил это к методу drop
. Если dragNodeInsertToParent
равно true
, найдите индекс узла в месте назначения отбрасывания и pu sh узел, который нужно вставить в его дочерний массив.
if (this.dragNodeInsertToParent) {
const indexOfParent = newSiblings.findIndex( element => element.id === nodeAtDest.id);
newSiblings[indexOfParent].children.push(nodeToInsert);
} else {
newSiblings.splice(relativeIndex, 0, nodeToInsert);
}
Теперь, если вы вытащите узел достаточно далеко вправо, включится режим вставки, и вы сможете добавить дочерний элемент обратно в пустой родительский узел:
В любом случае, все еще продолжая работать над этим, если у кого-то есть какие-либо идеи для того, чтобы сделать эту работу более интуитивно, пожалуйста, оставьте комментарий.