【问题标题】:Angular Cdk Drag and drop, constant length listsAngular Cdk 拖放,等长列表
【发布时间】:2020-09-29 21:37:05
【问题描述】:

我已经在这个问题上绞尽脑汁很久了。我想要实现的是有两个连接的具有恒定长度的拖放列表。这意味着如果我将一个元素从一个列表移动到另一个列表,则一个项目将被推送到另一个列表。这在cdkDropListDropped 事件期间当然是微不足道的,但我希望它在项目被拖到列表上时立即发生。

我的大部分尝试都涉及使用cdkDropListEntered 事件来:

  1. 尝试简单地移动数据数组中的项目:
public enter(list: number, event: CdkDragEnter<User[]>) {
  if (list === 0) {
    let data = this.schedule.responsible.pop();
    this.schedule.queue.unshift(data);
  } else {
    let data = this.schedule.queue.shift();
    this.schedule.responsible.push(data);
  }
}

这导致了以下类型的错误:

core.js:6185 ERROR DOMException: Failed to execute 'insertBefore' on 'Node': 要插入新节点的节点不是该节点的子节点

  1. 尝试使用CdkDropList addItem()removeItem()getSortedItems()。这会导致类似的问题。

  2. 尝试使用 Renderer2 移动 DOM 元素本身(并且保持数据不变)

有什么方法可以实现我想要的吗?

This 华丽的绘画有助于解释我想要实现的目标。

【问题讨论】:

    标签: angular angular-cdk angular-cdk-drag-drop


    【解决方案1】:

    好的,在尝试了两种解决方案后我已经弄清楚了。第一个涉及将占位符框添加到两个列表中,只有在它们有内容时才可见。它们的内容将是推入该列表的框的内容。同时,原始框被赋予display: none 样式。这主要实现了我想要的行为,但由于可拖动的内部模型和 DOM 之间的不匹配,存在一些视觉问题。

    最终的结果是放弃了首先拥有两个列表的概念。然后排序自然而然地解决了。但是,样式必须稍有不同,因为每个可拖动对象都必须是列表的直接后代。

    附上代码和 Stackblitz 示例:

    app.component.ts

    import { Component, OnInit} from '@angular/core';
    import {CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';
    
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent implements OnInit {
    
        public lists: {list1: string[], list2: string[]};
        public fullList: string[];
        public numList1: number;
    
        constructor() {}
    
        ngOnInit() {
            this.lists = {
                list1: ['one', 'two'],
                list2: ['three', 'four']
            };
            this.fullList = this.lists.list1.concat(this.lists.list2);
            this.numList1 = this.lists.list1.length;
        }
    
        public drop(event: CdkDragDrop<string[]>) {
            moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
        }
    }
    

    app.component.html

    <div class="list-container">
      <div cdkDropList
          [cdkDropListAutoScrollDisabled]="true"
          [cdkDropListData]="fullList"
          cdkDropListLockAxis="y"
          (cdkDropListDropped)="drop($event)">
        <ng-container *ngFor="let item of fullList; let index = index;">
          <h2 *ngIf="index === 0">List 1</h2>
          <h2 *ngIf="index === numList1">List 2</h2>
          <div cdkDrag class="drop-box">{{item}}</div>
        </ng-container>
      </div>
    </div>
    

    Stackblitz:https://stackblitz.com/edit/angular-ivy-s7zfye

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 2021-01-14
      • 2019-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多