Open
Description
What are you trying to do?
I try to move a dynamically inserted component from one cdkDropList
to another inside of a cdkDropListGroup
.
Here an excerpt of the HTML:
<div class="container-fluid mt-3">
<div class="row" cdkDropListGroup>
<div class="col-4 border min-vh-100" #dropList0Ref
cdkDropList
[cdkDropListData]="columns[0]"
(cdkDropListDropped)="onDrop($event)">
<ng-container #componentContainer0></ng-container>
</div>
<div class="col-4 border min-vh-100" #dropList1Ref
cdkDropList
[cdkDropListData]="columns[1]"
(cdkDropListDropped)="onDrop($event)">
<ng-container #componentContainer1></ng-container>
</div>
<div class="col-4 border min-vh-100" #dropList2Ref
cdkDropList
[cdkDropListConnectedTo]="['dropList0Ref', 'dropList1Ref']"
[cdkDropListData]="columns[2]"
(cdkDropListDropped)="onDrop($event)">
<ng-container #componentContainer2></ng-container>
</div>
</div>
</div>
excerpt of component.ts
...
columns: any[] = [ [], [], [] ];
components0: ComponentRef<any>[] = [];
components1: ComponentRef<any>[] = [];
components2: ComponentRef<any>[] = [];
@ViewChild('componentContainer0', { static: true, read: ViewContainerRef })
componentContainer0: ViewContainerRef;
@ViewChild('componentContainer1', { static: true, read: ViewContainerRef })
componentContainer1: ViewContainerRef;
@ViewChild('componentContainer2', { static: true, read: ViewContainerRef })
componentContainer2: ViewContainerRef;
ngAfterViewInit () {
this.add(LogBookComponent, 0);
this.add(CustomerListComponent, 0);
}
add (component, columnIndex: number) {
let componentFactory;
let cmp: ComponentRef<any>;
let id;
switch (columnIndex) {
case 0:
componentFactory = this.resolver.resolveComponentFactory(component);
cmp = this.componentContainer0.createComponent(componentFactory);
this.components0.push(cmp);
id = cmp.componentType.name;
this.columns[ 0 ].push({ id, title: `Gadget ${ id }` });
cmp.changeDetectorRef.detectChanges();
break;
case 1:
componentFactory = this.resolver.resolveComponentFactory(component);
cmp = this.componentContainer1.createComponent(componentFactory);
id = cmp.componentType.name;
this.components1.push(cmp);
this.columns[ 1 ].push({ id, title: `Gadget ${ id }` });
cmp.changeDetectorRef.detectChanges();
break;
case 2:
componentFactory = this.resolver.resolveComponentFactory(component);
cmp = this.componentContainer2.createComponent(componentFactory);
id = cmp.componentType.name;
this.components2.push(cmp);
this.columns[ 2 ].push({ id, title: `Gadget ${ id }` });
cmp.changeDetectorRef.detectChanges();
break;
default:
throw new Error('only three columns are supported');
}
}
onDrop (event: CdkDragDrop<{}[]>) {
console.log(``);
console.log(``);
console.log(``);
console.log('event', event);
console.log('this.columns', this.columns);
const previousContainerId = this.getIdOf(event.previousContainer.id);
const currentContainerId = this.getIdOf(event.container.id);
console.log('previousContainerId', previousContainerId);
console.log('currentContainerId', currentContainerId);
if (event.previousContainer == event.container) {
console.log(`moving inside ${ event.previousIndex } -> ${ event.currentIndex }`);
switch (currentContainerId) {
case 0:
this.componentContainer0.move(this.components0[ event.previousIndex ].hostView, event.currentIndex);
moveItemInArray(this.components0, event.previousIndex, event.currentIndex);
break;
case 1:
this.componentContainer1.move(this.components1[ event.previousIndex ].hostView, event.currentIndex);
moveItemInArray(this.components1, event.previousIndex, event.currentIndex);
break;
case 2:
this.componentContainer2.move(this.components2[ event.previousIndex ].hostView, event.currentIndex);
moveItemInArray(this.components2, event.previousIndex, event.currentIndex);
break;
}
}
else {
console.log(`transferring ${ previousContainerId } -> ${ currentContainerId } (${ event.previousIndex } -> ${ event.currentIndex })`);
let previousComponents;
let currentComponents;
transferArrayItem(previousComponents, currentComponents, event.previousIndex, event.currentIndex);
transferArrayItem(this.columns[ previousContainerId ], this.columns[ currentContainerId ], event.previousIndex, event.currentIndex);
switch (currentContainerId) {
case 0:
currentComponents = this.components0;
switch (previousContainerId) {
case 0:
// not possible is an move in array
console.log(`not possible is an move in array`);
break;
case 1:
previousComponents = this.components1;
this.componentContainer0.move(this.components1[ event.previousIndex ].hostView, event.currentIndex);
break;
case 2:
previousComponents = this.components2;
this.componentContainer0.move(this.components2[ event.previousIndex ].hostView, event.currentIndex);
break;
}
break;
case 1:
currentComponents = this.components1;
switch (previousContainerId) {
case 0:
previousComponents = this.components0;
this.componentContainer1.move(this.components0[ event.previousIndex ].hostView, event.currentIndex);
break;
case 1:
// not possible is an move in array
console.log(`not possible is an move in array`);
break;
case 2:
previousComponents = this.components2;
this.componentContainer1.move(this.components2[ event.previousIndex ].hostView, event.currentIndex);
break;
}
break;
case 2:
currentComponents = this.components2;
switch (previousContainerId) {
case 0:
previousComponents = this.components0;
this.componentContainer2.move(this.components0[ event.previousIndex ].hostView, event.currentIndex);
break;
case 1:
previousComponents = this.components1;
this.componentContainer2.move(this.components1[ event.previousIndex ].hostView, event.currentIndex);
break;
case 2:
// not possible is an move in array
console.log(`not possible is an move in array`);
break;
}
break;
}
}
}
...
Reproduction
I'm able to move both components inside one cdkDropList
. I also can move from on to another cdkDropList
. But if I try to move it back to first cdkDropList
or move it inside the new cdkDropList
, an error occurs. If I debug the $event
the event.previousContainer.id
is still 0
. So something wasn't updated. But I don't know what.
I know there are way's to write it shorter but before starting refactoring I need a working drag and drop.
StackBlitz: https://stackblitz.com/edit/angular-ivy-iuwvmb?file=src%2Fapp%2Fapp.component.ts
Steps to reproduce in Stackblitz:
- Move Hello Component 1 to second column
- Try to move Hello Component 1 back to first column
- see debug information and error in console
Environment
- Angular: 9.1.9
- CDK/Material: 9.2.4
- Browser(s): Chrome
- Operating System (e.g. Windows, macOS, Ubuntu): macOS