OrYo
OrYo

Reputation: 193

How to create list of Component for drag and drop CDK angular

I trying to create drag and drop to list Components with drag and drop CDK of angular, like below, but the Components are not displayed properly.

App.component.ts

import { RightSideCombinedComponent } from './right-side.component';
import { LeftSideComponent } from './left-side.component';
@Component({
  selector: 'app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

innerComponenets: Array<any> = [
  RightSideCombinedComponent,
  LeftSideComponent,
  ];
constructor() { }

  ngOnInit(): void {
  }

  

  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.innerComponenets, event.previousIndex, event.currentIndex);
  }

<div cdkDropList cdkDropListOrientation="horizontal" class="example-list" (cdkDropListDropped)="drop($event)">
            <div class="example-box" *ngFor="let item of innerComponenets"  cdkDrag>
                {{item}}
                </div>

the screen displayed (The code of the components is displayed instead of the display of the components): Before drag and drop: enter image description here

Drag and drop: enter image description here

After drag and drop: enter image description here

Does anyone know how to do it right?

Upvotes: 0

Views: 908

Answers (3)

Eliseo
Eliseo

Reputation: 57929

array=[0,1];

<div cdkDropList cdkDropListOrientation="horizontal" class="example-list"
      (cdkDropListDropped)="drop($event)">
  <div class="example-box" *ngFor="let item of array" cdkDrag>
      <app-left-side *ngIf="item==0"></app-left-side>
      <app-right-side *ngIf="item==1"></app-right-side>
  </div>
</div>

a stackblitz

See that you only interchange the elements of the array [0,1]. If this array who say to Angular which component must show in first time

NOTE: This tecnica only is util if we don't store data in the components, think that each drop the components are new and initializeted

Upvotes: 1

PPik
PPik

Reputation: 11

Please provide more details. Especially the code of moveItemInArray code and how you reached this.innerComponenets (what hook used and what type).

Result would also suggest you are hooking to prototype instead of instance of HtmlElement.

EDIT:

You need to instantiate components in array. In your array you have prototypes of the right and left component. What you need now to do is for example to build array of INSTANCES of the components. in example ;ike so :

for (const component of innerComponenets) {
     const componentRef = viewContainerRef.createComponent<componentModel or any>(component);
innerComponentsInstancesReferences.push( componentRef);
    }

That componentRef array containing INSTANCES you use in ngFor. Then Templates/View would understand that you want REFERENCED INSTANCES components to be displayed. Now you did simply "tell" to tamplate "display to me prototype of my components"

please refere to the article: https://angular.io/guide/dynamic-component-loader

and componentRef type documentation: https://angular.io/api/core/ViewContainerRef

Types are ESSENTIAL

PS> May work also if you use [ngFor] that would not use STRING but would EVALUATE probably your component so shortly speaking instantiate it. I am not sure if that would work

Upvotes: 0

Edmunds Folkmanis
Edmunds Folkmanis

Reputation: 572

Statement {{item}} displays values from array innerComponenets that are actually constructor functions. They are draggable thanks to the directive cdkDrag on containing <div> element.

If you have some static list of draggable components, you don't need any array and *ngFor structural directive. Just put them one after one in html code.

<app-left-side cdkDrag></app-left-side>
<app-right-side cdkDrag></app-right-side>

Upvotes: 0

Related Questions