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

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

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

【问题讨论】:

    标签: angular drag-and-drop angular-material angular7 angular-cdk


    【解决方案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"
          猜你喜欢
          • 2023-03-10
          • 2019-04-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多