angular - CDK Drag Drop ändrar inte korrekt positionen på bilder
Jag skapade ett bildgalleri och jag tänker ändra positionen mellan dem. För detta använder jag Drag & Drop cdk-biblioteket.
Mitt problem är att utbytet av bilder inte alltid sker korrekt, ibland byter jag den första bilden med den andra och detta byte sker inte.
Hur kan jag få detta helt fungerande, horisontellt och vertikalt?
Finns det ett sätt att Drag endast kan starta om bilden är lagrad i klassen mdc-image-list - with-text-protection?
Tack!
DEMO
.HTML
<ul class="mdc-image-list my-image-list" style="padding-left: 10px;padding-right: 10px;" cdkDropList [cdkDropListData]="data"
(cdkDropListDropped)="drop($event)">
<ng-container *ngFor="let product of data; let j = index;">
<li class="mdc-image-list__item" cdkDrag>
<div class="mdc-image-list__image-aspect-container">
<ng-container *ngIf="product.image == null; else productImage">
<img src="" class="mdc-image-list__image imagenotfound">
</ng-container>
<ng-template #productImage>
<img [src]="product.image" class="mdc-image-list__image">
</ng-template>
</div>
<div class="mdc-image-list--with-text-protection">
<div class="mdc-image-list__supporting mdc-image-list__supporting">
<span class="mdc-image-list__label">{{product.name}}</span>
</div>
</div>
</li>
</ng-container>
</ul>
.ts
drop(event: CdkDragDrop<string[]>) {
if (event.previousContainer === event.container) {
moveItemInArray(
event.container.data,
event.previousIndex,
event.currentIndex
);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex
);
}
}
Svar #1
Det enda sättet jag hittar för att tillåta drag och släpp i ett rutnät är att varje element i rutnätet var en cdkDropList.
Annons: Elementen rör sig inte medan vi drar
Tja, eftersom data för varje cdkDropList kommer att vara ett objekt, är datan vi vill transportera och indexet
[cdkDropListData]="{item:product,index:j}"
Så, vår funktion dropEvent ändrar arrayens data enligt dessa värden
drop(event: CdkDragDrop<any>) {
this.data[event.previousContainer.data.index]={...event.container.data.item}
this.data[event.container.data.index]={...event.previousContainer.data.item}
event.currentIndex=0;
}
Ja! Vi är inte tvungna att använda droppen som visar exemplen. Tänk att det enda vi vill är att ändra en array.
Det finns en annan sak att göra, se till att "dragPlaceHolder" blir en tom div
<div cdkDrag>
....
<div *cdkDragPlaceholder></div>
</div>
Tja, html är lite komplex eftersom den egna mdc-image-list är komplex. Det är viktigt att notera att alla cdkDropList måste vara omslutna i en div ckdDropListGroup
<div cdkDropListGroup>
<ul class="mdc-image-list my-image-list" style="padding-left: 10px;padding-right: 10px;">
<ng-container *ngFor="let product of data; let j = index;">
<li class="mdc-image-list__item" cdkDropList [cdkDropListData]="{item:product,index:j}"
cdkDropListOrientation="horizontal" (cdkDropListDropped)="drop($event)">
<div cdkDrag>
<div class="mdc-image-list__image-aspect-container">
<ng-container *ngIf="product.image == null; else productImage">
<img src="" class="mdc-image-list__image imagenotfound">
</ng-container>
<ng-template #productImage>
<img [src]="product.image" class="mdc-image-list__image">
</ng-template>
</div>
<div class="mdc-image-list--with-text-protection">
<div class="mdc-image-list__supporting mdc-image-list__supporting">
<span class="mdc-image-list__label">{{product.name}}</span>
</div>
</div>
<div class="example-custom-placeholder" *cdkDragPlaceholder></div>
</div>
</li>
</ng-container>
</ul>
</div>
här är din forkade stackblitz
OBS: Om någon vill ha ett enklare exempel, se detta andra stackblitz
