如何在两个组件之间使用 Angular7 (angular material) 拖放

How to use Angular7 (angular material) drag drop between two components

最近 angular 在 angular material 中引入了拖放功能 https://material.angular.io/cdk/drag-drop/overview.

所有示例都在单个组件中描述。如何在两个不同的组件中使用它,将一个组件项目拖放到另一个组件中。

您可以使用属性 idcdkDropListConnectedTo 到 link 两个列表:

组件 1:

<div cdkDropList id="list-1" cdkDropListConnectedTo="list-2" (cdkDropListDropped)="drop($event)">
    <div *ngFor="let item of list" cdkDrag>{{ item }}</div>
</div>

组件 2:

<div cdkDropList id="list-2" cdkDropListConnectedTo="list-1" (cdkDropListDropped)="drop($event)">
  <div *ngFor="let item of list" cdkDrag>{{ item }}</div>
</div>

如果您需要将多个列表连接到一个列表,您可以使用以下语法:[cdkDropListConnectedTo]="['list-1', 'list-2', 'list-3', 'list-4']"

在 link 列表之后,您必须根据操作正确更新一个或两个列表。您可以像这样在 drop 函数上执行此操作:

drop(event: CdkDragDrop<string[]>) {
    if (event.container.id === event.previousContainer.id) {
      // move inside same list
      moveItemInArray(this.list, event.previousIndex, event.currentIndex);
    } else {
      // move between lists
    }
}

对于在列表之间移动项目,您可能希望集中跟踪列表。您可以通过使用服务、商店或其他方法来实现。

不确定上述解决方案是否仍然适用于 angular 7.2.9 和 angular material/cdk 7.3.5

它对我不起作用,因此在经历了一些困难之后 - 我设法使用 cdkDropListGroup 指令使其工作。 cdkDropListGroup 中的所有 cdkDropList 都可以放置物品。您不再需要使用 cdkDropListConnectedTo 属性

连接下拉列表
<div cdkDropListGroup>
<component1></component1>
<component2></component2>
</div>

组件 1

<div cdkDropList id="list-1" cdkDropListConnectedTo="list-2" (cdkDropListDropped)="drop($event)">
    <div *ngFor="let item of list" cdkDrag>{{ item }}</div>
</div>

组件 2

<div cdkDropList id="list-2" cdkDropListConnectedTo="list-1" (cdkDropListDropped)="drop($event)">
  <div *ngFor="let item of list" cdkDrag>{{ item }}</div>
</div>

两个组件的共享服务

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);
        }
    }

父组件

<div cdkDropListGroup>
<component1></component1>
<component2></component2>
</div>

从两个组件调用 drop 方法

drop(event: CdkDragDrop<string[]>) {
      this.sharedService.drop(event);
  }

您只需在服务中创建一个 drop 方法并从两个组件调用该 drop 方法。并且必须在父组件上用 cdkDropListGroup 包装这两个组件。

应用组件

<div class="wrapper">
  <div cdkDropListGroup>
    <app-test1></app-test1>
    <app-test2></app-test2>
  </div>
</div>

测试 1 组件

<div class="container">
  <h2>Movies</h2>
  <div cdkDropList [cdkDropListData]="MoviesList"
    class="movie-list" (cdkDropListDropped)="onDrop($event)">
    <div class="movie-block" *ngFor="let moviesList of MoviesList" cdkDrag>{{moviesList}}</div>
  </div>
</div>

  export class Test1Component implements OnInit {

  constructor(private ss: ShareService) { }

  ngOnInit() {
  }

  // Transfer Items Between Lists
  MoviesList = [
    'The Far Side of the World',
    'Morituri',
    'Napoleon Dynamite',
    'Pulp Fiction',
    'Blade Runner',
    'Cool Hand Luke',
    'Heat',
    'Juice'    
  ];


  onDrop(event: CdkDragDrop<string[]>) {
    this.ss.drop(event);
  }

}

测试 2 组件

<div class="container">
  <h2>Movies Watched</h2>
  <div cdkDropList [cdkDropListData]="MoviesWatched"
    [cdkDropListConnectedTo]="list-1" class="movie-list" (cdkDropListDropped)="onDrop($event)">
    <div class="movie-block" *ngFor="let moviesWatched of MoviesWatched" cdkDrag>{{moviesWatched}}</div>
  </div>
</div>

import { Component, OnInit } from '@angular/core';
import { CdkDragDrop } from '@angular/cdk/drag-drop';
import { ShareService } from '../share.service';


@Component({
  selector: 'app-test2',
  templateUrl: './test2.component.html',
  styleUrls: ['./test2.component.css']
})
export class Test2Component implements OnInit {

  constructor(private ss: ShareService) { }

  MoviesWatched = [
   'Transformers'
  ];

  ngOnInit() {
  }

  onDrop(event: CdkDragDrop<string[]>) {
    this.ss.drop(event);
  }

}

ShareService

import { Injectable } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';


@Injectable()
export class ShareService {

  constructor() { }

  public 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);
    }
  }

}

这是工作link

要连接多个列表然后使用拖放中的打击代码

[cdkDropListConnectedTo]="['element-1', 'element-2', 'element-3', 'element-4']"