Angular Функциональность перетаскивания cdk материала работает так же, когда он восстанавливает видимость элемента и вставляет его в его старую позицию в DOM .
Важно, чтобы они сохраняют позицию , потому что они передают ngFor
директиву , и перемещение элемента в DOM может сбрасывать NgFor
, который выполняет умное различие и воссоздает элементы только тогда, когда необходимо .
Это означает, что если вы хотите, чтобы он работал без ngFor, тогда вам нужно перемещать html элементов самостоятельно.
Вот пример того, как это можно сделать :
Stackblitz с ручными манипуляциями с домом
drop(event: CdkDragDrop<any[]>) {
const nodeToMove = event.item.element.nativeElement;
const { previousContainer, container, previousIndex, currentIndex } = event;
console.log(this.sidebar, this.main);
if (previousContainer === container) {
moveItemInArray(container.data, previousIndex, currentIndex);
moveWithinContainer(
container.element.nativeElement,
previousIndex,
currentIndex
);
} else {
transferArrayItem(
previousContainer.data,
container.data,
previousIndex,
currentIndex
);
transferNodeToContainer(
nodeToMove,
container.element.nativeElement,
currentIndex
);
Promise.resolve().then(() => {
previousContainer.removeItem(event.item);
event.item.dropContainer = container;
event.item._dragRef._withDropContainer(container._dropListRef);
container.addItem(event.item);
});
}
}
...
function moveWithinContainer(container, fromIndex, toIndex) {
if (fromIndex === toIndex) {
return;
}
const nodeToMove = container.children[fromIndex];
const targetNode = container.children[toIndex];
if (fromIndex < toIndex) {
targetNode.parentNode.insertBefore(nodeToMove, targetNode.nextSibling);
} else {
targetNode.parentNode.insertBefore(nodeToMove, targetNode);
}
}
function transferNodeToContainer(node, container, toIndex) {
if (toIndex === container.children.length) {
container.appendChild(node);
} else {
const targetItem = container.children[toIndex];
targetItem.parentNode.insertBefore(node, targetItem);
}
}
NgFor
Как вы могли заметить, приведенное выше решение немного взломано и может быть взломано в зависимости от версии библиотеки.
Вместо этого вы можете использовать директиву ngFor:
ts
sidebar = [0, 1, 2];
main = [0, 1];
html
<div *ngFor="let item of sidebar" class="example-box" cdkDrag>
<app-demo-comp-2 *ngIf="item === 0" [btn]=2></app-demo-comp-2>
<app-demo-comp *ngIf="item === 1" [ddn]=2></app-demo-comp>
<app-demo-comp-3 *ngIf="item === 2" [txt]=3></app-demo-comp-3>
</div>
...
<div *ngFor="let item of main" class="example-box" cdkDrag>
<app-demo-comp *ngIf="item === 0" [ddn]=1></app-demo-comp>
<app-demo-comp-2 *ngIf="item === 1" [btn]=3></app-demo-comp-2>
</div>
Stackblitz с NgFor реализация