在Angular 18中,我已经使用角drag&Dropcdk(您可以在此处看到更好的示例)实现了一个简单的组件:
import {Component} from '@angular/core';
import {
CdkDrag,
CdkDragDrop,
CdkDragPlaceholder,
CdkDropList,
moveItemInArray,
} from '@angular/cdk/drag-drop';
@Component({
standalone: true,
selector: 'cdk-drag-drop-custom-placeholder-example',
template: `<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
@for (movie of movies; track movie) {
<button (click)="moveUp(movie)">Up</button>
<button (click)="moveDown(movie)">Down</button>
<div class="example-box" cdkDrag>
<div class="example-custom-placeholder" *cdkDragPlaceholder></div>
{{movie}}
</div>
}
</div>`,
styleUrl: 'cdk-drag-drop-custom-placeholder-example.css',
imports: [CdkDropList, CdkDrag, CdkDragPlaceholder],
})
export class CdkDragDropCustomPlaceholderExampleComponent {
movies = [
'Episode I - The Phantom Menace',
'Episode II - Attack of the Clones',
'Episode III - Revenge of the Sith',
'Episode IV - A New Hope',
'Episode V - The Empire Strikes Back',
];
moveUp(item: string) {
const index = this.movies.indexOf(item);
moveItemInArray(this.movies, index, index - 1);
}
moveDown(item: string) {
const index = this.movies.indexOf(item);
moveItemInArray(this.movies, index, index + 1);
}
drop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.movies, event.previousIndex, event.currentIndex);
}
}
该简单的代码有效,在拖动电影时,有动画在数组中移动它们,
当使用按钮向上/向下移动项目时,问题开始 他们正在切换地方,但立即没有动画。 我很想知道如何在手动更改阵列时启用动画。 谢谢!
moveUp(item: item) {
this.animateMove(item, 'up');
}
moveDown(item: item) {
this.animateMove(item, 'down');
}
animateMove(item: item, direction: 'up' | 'down') {
const index = this.itemList().indexOf(item);
const element = document.getElementById(item.questionId.toString());
if (element) {
this.renderer.setStyle(element, 'transition', 'transform 0.3s ease');
this.renderer.setStyle(
element,
'transform',
`translate3d(0px, ${direction === 'up' ? '-60px' : '60px'}, 0px)`,
);
const changeWithElement =
direction === 'up'
? (element.previousElementSibling as HTMLElement)
: (element.nextElementSibling as HTMLElement);
console.log('current', element);
console.log('previes', changeWithElement);
this.renderer.setStyle(
changeWithElement,
'transition',
'transform 0.3s ease',
);
this.renderer.setStyle(
changeWithElement,
'transform',
`translate3d(0px, ${direction === 'up' ? '60px' : '-60px'}, 0px)`,
);
setTimeout(() => {
this.renderer.removeStyle(element, 'transition');
this.renderer.removeStyle(element, 'transform');
this.renderer.removeStyle(changeWithElement, 'transition');
this.renderer.removeStyle(changeWithElement, 'transform');
moveItemInArray(
this.rulesList(),
index,
direction === 'up' ? index - 1 : index + 1,
);
this.updateGlobalRatings();
}, 300);
}
}
我还为这样的每个DIV项目添加了ID:
<div
class="list-item"
[class.opacity-40]="isDragging"
(cdkDragStarted)="onDragStarted()"
(cdkDragReleased)="onDragReleased()"
cdkDrag
[id]="item.questionId"
>
其背后的概念是跟踪我要移动的元素,然后通过按钮我将其预览元素或下一个元素,然后将其添加到两个方面的正确样式,以使动画起作用(只需添加添加样式没有完成这项工作)这是解决方法,但对我的情况很棒,做诸如洗牌会或更换彼此相邻的不同元素位置之类的事情都需要采取所需的元素ID以及所有在每个之间的元素,并分别更改每个元素的过渡。如果某人有更好的解决方案,也许可以使用拖放功能和属性来共享此处(: