如何在两个组件之间使用Angular7(角度材料)拖放

Posted

技术标签:

【中文标题】如何在两个组件之间使用Angular7(角度材料)拖放【英文标题】:How to use Angular7 (angular material) drag drop between two components 【发布时间】:2019-04-24 02:06:40 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

应用组件

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

Test1 组件

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


Test2 组件

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


共享服务

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

【讨论】:

【参考方案3】:

组件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);
  

【讨论】:

【参考方案4】:

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

它对我不起作用,因此经过一段时间的努力 - 我设法使用 cdkDropListGroup 指令使其工作。 cdkDropListGroup 中的所有 cdkDropList 都可用于放置项目。您不再需要使用 cdkDropListConnectedTo 属性连接 Drop Lists

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

【讨论】:

你的实现是什么,你能提供示例,因为我现在面临这个问题并且没有connectedTo它不起作用。我有一个带有列表的组件,其中实现了拖放,我想在这样的组中使用它。 拯救了这一天!【参考方案5】:

您可以使用属性 idcdkDropListConnectedTo 来链接两个列表:

组件 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']"

链接列表后,您必须根据操作正确更新一个或两个列表。您可以像这样在 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
    

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

【讨论】:

谢谢。这对于单个拖动块来说很好,如果我想要多个像 [cdkDropListConnectedTo]="[list-2,list-3,list-4] 不起作用。如何实现这一点 @JomyJoseph 我已经更新了答案,包括支持多个列表之间的链接。如果这解决了您的问题,请接受答案。如果没有,请告诉我们。 当然。你是摇滚。我错过了每个 id 的单引号。 在角度 7.2.1 中,我必须在 cdkDropListConnectedTo 周围使用 [] 才能使用一个列表。 [cdkDropListConnectedTo]="[list-1]"[cdkDropListConnectedTo]="['list-1']" @Dirk 使用 angular 7.2.0 和 angular material/cdk 7.2.1 对其进行了测试,它使用与以前相同的语法:cdkDropListConnectedTo="list-1"

以上是关于如何在两个组件之间使用Angular7(角度材料)拖放的主要内容,如果未能解决你的问题,请参考以下文章

角度材料:反应性与模板?

如何*保存*角度材料模态对话框的结果?

如何使用响应式表单将验证器添加到表单控件以从角度材料进行匹配输入

最小化角度材质对话框

如何更改角度组件的活动材料列表材料列表项颜色?

角度 => 里面有材料表的表格问题